From c04515a844cf9348198fb16c637466604a94fc09 Mon Sep 17 00:00:00 2001 From: freddygv Date: Mon, 8 Aug 2022 01:41:00 -0600 Subject: [PATCH] Use proto message for each secrets write op Previously there was a field indicating the operation that triggered a secrets write. Now there is a message for each operation and it contains the secret ID being persisted. --- agent/consul/fsm/commands_oss.go | 4 +- agent/consul/fsm/snapshot_oss_test.go | 36 +- agent/consul/peering_backend.go | 2 +- agent/consul/state/peering.go | 172 ++- agent/consul/state/peering_test.go | 439 ++++-- .../services/peerstream/server.go | 2 +- .../services/peerstream/server_test.go | 11 +- .../services/peerstream/stream_resources.go | 35 +- .../services/peerstream/stream_test.go | 119 +- agent/rpc/peering/service.go | 27 +- proto/pbpeering/peering.go | 31 +- proto/pbpeering/peering.pb.binary.go | 44 +- proto/pbpeering/peering.pb.go | 1261 ++++++++++------- proto/pbpeering/peering.proto | 60 +- sdk/testutil/testlog.go | 2 +- 15 files changed, 1453 insertions(+), 792 deletions(-) diff --git a/agent/consul/fsm/commands_oss.go b/agent/consul/fsm/commands_oss.go index fcfeea699d..c8512569d0 100644 --- a/agent/consul/fsm/commands_oss.go +++ b/agent/consul/fsm/commands_oss.go @@ -720,9 +720,9 @@ func (c *FSM) applyPeeringDelete(buf []byte, index uint64) interface{} { } func (c *FSM) applyPeeringSecretsWrite(buf []byte, index uint64) interface{} { - var req pbpeering.PeeringSecretsWriteRequest + var req pbpeering.SecretsWriteRequest if err := structs.DecodeProto(buf, &req); err != nil { - panic(fmt.Errorf("failed to decode peering write request: %v", err)) + panic(fmt.Errorf("failed to decode peering secrets write request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "peering_secrets"}, time.Now(), diff --git a/agent/consul/fsm/snapshot_oss_test.go b/agent/consul/fsm/snapshot_oss_test.go index 36aad18538..2a04c701b7 100644 --- a/agent/consul/fsm/snapshot_oss_test.go +++ b/agent/consul/fsm/snapshot_oss_test.go @@ -483,18 +483,13 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) { ID: "1fabcd52-1d46-49b0-b1d8-71559aee47f5", Name: "baz", }, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: "1fabcd52-1d46-49b0-b1d8-71559aee47f5", - Establishment: &pbpeering.PeeringSecrets_Establishment{ - SecretID: "389bbcdf-1c31-47d6-ae96-f2a3f4c45f84", - }, - Stream: &pbpeering.PeeringSecrets_Stream{ - PendingSecretID: "0b7812d4-32d9-4e54-b1b3-4d97084982a0", - ActiveSecretID: "baaeea83-8419-4aa8-ac89-14e7246a3d2f", + SecretsRequest: &pbpeering.SecretsWriteRequest{ + PeerID: "1fabcd52-1d46-49b0-b1d8-71559aee47f5", + Request: &pbpeering.SecretsWriteRequest_PromotePending{ + PromotePending: &pbpeering.SecretsWriteRequest_PromotePendingRequest{ + ActiveStreamSecret: "baaeea83-8419-4aa8-ac89-14e7246a3d2f", }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_GENERATETOKEN, }, })) @@ -505,6 +500,27 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) { RootPEMs: []string{"qux certificate bundle"}, })) + // Issue two more secrets writes so that there are three secrets associated with the peering: + // - Establishment: "389bbcdf-1c31-47d6-ae96-f2a3f4c45f84" + // - Pending: "0b7812d4-32d9-4e54-b1b3-4d97084982a0" + // - Active: "baaeea83-8419-4aa8-ac89-14e7246a3d2f" + require.NoError(t, fsm.state.PeeringSecretsWrite(34, &pbpeering.SecretsWriteRequest{ + PeerID: "1fabcd52-1d46-49b0-b1d8-71559aee47f5", + Request: &pbpeering.SecretsWriteRequest_ExchangeSecret{ + ExchangeSecret: &pbpeering.SecretsWriteRequest_ExchangeSecretRequest{ + PendingStreamSecret: "0b7812d4-32d9-4e54-b1b3-4d97084982a0", + }, + }, + })) + require.NoError(t, fsm.state.PeeringSecretsWrite(33, &pbpeering.SecretsWriteRequest{ + PeerID: "1fabcd52-1d46-49b0-b1d8-71559aee47f5", + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ + EstablishmentSecret: "389bbcdf-1c31-47d6-ae96-f2a3f4c45f84", + }, + }, + })) + // Snapshot snap, err := fsm.Snapshot() require.NoError(t, err) diff --git a/agent/consul/peering_backend.go b/agent/consul/peering_backend.go index cda4f16d49..0f8b009e9c 100644 --- a/agent/consul/peering_backend.go +++ b/agent/consul/peering_backend.go @@ -141,7 +141,7 @@ func (b *PeeringBackend) ValidateProposedPeeringSecret(id string) (bool, error) return b.srv.fsm.State().ValidateProposedPeeringSecretUUID(id) } -func (b *PeeringBackend) PeeringSecretsWrite(req *pbpeering.PeeringSecretsWriteRequest) error { +func (b *PeeringBackend) PeeringSecretsWrite(req *pbpeering.SecretsWriteRequest) error { _, err := b.srv.raftApplyProtobuf(structs.PeeringSecretsWriteType, req) return err } diff --git a/agent/consul/state/peering.go b/agent/consul/state/peering.go index 87fd75f1ea..cfadb10f27 100644 --- a/agent/consul/state/peering.go +++ b/agent/consul/state/peering.go @@ -174,7 +174,7 @@ func peeringSecretsReadByPeerIDTxn(tx ReadTxn, ws memdb.WatchSet, id string) (*p return secret, nil } -func (s *Store) PeeringSecretsWrite(idx uint64, req *pbpeering.PeeringSecretsWriteRequest) error { +func (s *Store) PeeringSecretsWrite(idx uint64, req *pbpeering.SecretsWriteRequest) error { tx := s.db.WriteTxn(idx) defer tx.Abort() @@ -184,50 +184,55 @@ func (s *Store) PeeringSecretsWrite(idx uint64, req *pbpeering.PeeringSecretsWri return tx.Commit() } -func (s *Store) peeringSecretsWriteTxn(tx WriteTxn, req *pbpeering.PeeringSecretsWriteRequest) error { - if req == nil || req.Secrets == nil { +func (s *Store) peeringSecretsWriteTxn(tx WriteTxn, req *pbpeering.SecretsWriteRequest) error { + if req == nil || req.Request == nil { return nil } - - secret := req.GetSecrets() - if err := secret.Validate(); err != nil { - return err + if err := req.Validate(); err != nil { + return fmt.Errorf("invalid secret write request: %w", err) } - peering, err := peeringReadByIDTxn(tx, nil, secret.PeerID) + peering, err := peeringReadByIDTxn(tx, nil, req.PeerID) if err != nil { return fmt.Errorf("failed to read peering by id: %w", err) } if peering == nil { - return fmt.Errorf("unknown peering %q for secret", secret.PeerID) + return fmt.Errorf("unknown peering %q for secret", req.PeerID) } // If the peering came from a peering token no validation is done for the given secrets. // Dialing peers do not need to validate uniqueness because the secrets were generated elsewhere. if peering.ShouldDial() { - if err := tx.Insert(tablePeeringSecrets, secret); err != nil { + r, ok := req.Request.(*pbpeering.SecretsWriteRequest_Establish) + if !ok { + return fmt.Errorf("invalid request type %T when persisting stream secret for dialing peer", req.Request) + } + + secrets := pbpeering.PeeringSecrets{ + PeerID: req.PeerID, + Stream: &pbpeering.PeeringSecrets_Stream{ + ActiveSecretID: r.Establish.ActiveStreamSecret, + }, + } + if err := tx.Insert(tablePeeringSecrets, &secrets); err != nil { return fmt.Errorf("failed inserting peering: %w", err) } return nil } - if req.Operation == pbpeering.PeeringSecretsWriteRequest_OPERATION_UNSPECIFIED { - return fmt.Errorf("the operation that triggered the secrets write was not specified") - } - // If the peering token was generated locally, validate that the newly introduced UUID is still unique. // RPC handlers validate that generated IDs are available, but availability cannot be guaranteed until the state store operation. var newSecretID string - switch req.Operation { + switch r := req.Request.(type) { // Establishment secrets are written when generating peering tokens, and no other secret IDs are included. - case pbpeering.PeeringSecretsWriteRequest_OPERATION_GENERATETOKEN: - newSecretID = secret.GetEstablishment().GetSecretID() + case *pbpeering.SecretsWriteRequest_GenerateToken: + newSecretID = r.GenerateToken.EstablishmentSecret // When exchanging an establishment secret a new pending stream secret is generated. // Active stream secrets doesn't need to be checked for uniqueness because it is only ever promoted from pending. - case pbpeering.PeeringSecretsWriteRequest_OPERATION_EXCHANGESECRET: - newSecretID = secret.GetStream().GetPendingSecretID() + case *pbpeering.SecretsWriteRequest_ExchangeSecret: + newSecretID = r.ExchangeSecret.PendingStreamSecret } if newSecretID != "" { @@ -244,50 +249,101 @@ func (s *Store) peeringSecretsWriteTxn(tx WriteTxn, req *pbpeering.PeeringSecret } } - existing, err := peeringSecretsReadByPeerIDTxn(tx, nil, secret.PeerID) + existing, err := peeringSecretsReadByPeerIDTxn(tx, nil, req.PeerID) if err != nil { return err } + secrets := pbpeering.PeeringSecrets{ + PeerID: req.PeerID, + } + var toDelete []string - if existing != nil { - // Collect any overwritten UUIDs for deletion. - switch req.Operation { - case pbpeering.PeeringSecretsWriteRequest_OPERATION_GENERATETOKEN: - // Merge in existing stream secrets when persisting a new establishment secret. - // This is to avoid invalidating stream secrets when a new peering token - // is generated. - secret.Stream = existing.GetStream() - - // When a new token is generated we replace any un-used establishment secrets. - if existingEstablishment := existing.GetEstablishment().GetSecretID(); existingEstablishment != "" { - toDelete = append(toDelete, existingEstablishment) - } - - case pbpeering.PeeringSecretsWriteRequest_OPERATION_EXCHANGESECRET: - // Avoid invalidating existing active secrets when exchanging establishment secret for pending. - secret.Stream.ActiveSecretID = existing.GetStream().GetActiveSecretID() - - // When exchanging an establishment secret we invalidate the existing establishment secret. - if existingEstablishment := existing.GetEstablishment().GetSecretID(); existingEstablishment != "" { - toDelete = append(toDelete, existingEstablishment) - } - - // When exchanging an establishment secret unused pending secrets are overwritten. - if existingPending := existing.GetStream().GetPendingSecretID(); existingPending != "" { - toDelete = append(toDelete, existingPending) - } - - case pbpeering.PeeringSecretsWriteRequest_OPERATION_PROMOTEPENDING: - // Avoid invalidating existing establishment secrets when promoting pending secrets. - secret.Establishment = existing.GetEstablishment() - - // If there was previously an active stream secret it gets replaced in favor of the pending secret - // that is being promoted. - if existingActive := existing.GetStream().GetActiveSecretID(); existingActive != "" { - toDelete = append(toDelete, existingActive) - } + // Collect any overwritten UUIDs for deletion. + switch r := req.Request.(type) { + case *pbpeering.SecretsWriteRequest_GenerateToken: + // Store the newly-generated establishment secret, overwriting any that existed. + secrets.Establishment = &pbpeering.PeeringSecrets_Establishment{ + SecretID: r.GenerateToken.GetEstablishmentSecret(), } + + // Merge in existing stream secrets when persisting a new establishment secret. + // This is to avoid invalidating stream secrets when a new peering token + // is generated. + secrets.Stream = existing.GetStream() + + // When a new token is generated we replace any un-used establishment secrets. + if existingEstablishment := existing.GetEstablishment().GetSecretID(); existingEstablishment != "" { + toDelete = append(toDelete, existingEstablishment) + } + + case *pbpeering.SecretsWriteRequest_ExchangeSecret: + if existing == nil { + return fmt.Errorf("cannot exchange peering secret: no known secrets for peering") + } + + // Store the newly-generated pending stream secret, overwriting any that existed. + secrets.Stream = &pbpeering.PeeringSecrets_Stream{ + PendingSecretID: r.ExchangeSecret.GetPendingStreamSecret(), + + // Avoid invalidating existing active secrets when exchanging establishment secret for pending. + ActiveSecretID: existing.GetStream().GetActiveSecretID(), + } + + // When exchanging an establishment secret we invalidate the existing establishment secret. + if existingEstablishment := existing.GetEstablishment().GetSecretID(); existingEstablishment != "" { + toDelete = append(toDelete, existingEstablishment) + } else { + // When there is no existing establishment secret we must not proceed because another ExchangeSecret + // RPC already invalidated it. Otherwise, this operation would overwrite the pending secret + // from the previous ExchangeSecret. + return fmt.Errorf("invalid establishment secret: peering was already established") + } + + // When exchanging an establishment secret unused pending secrets are overwritten. + if existingPending := existing.GetStream().GetPendingSecretID(); existingPending != "" { + toDelete = append(toDelete, existingPending) + } + + case *pbpeering.SecretsWriteRequest_PromotePending: + if existing == nil { + return fmt.Errorf("cannot promote pending secret: no known secrets for peering") + } + if existing.GetStream().GetPendingSecretID() == "" { + // There is a potential race if multiple dialing clusters send an Open request with a valid + // pending secret. The secret could be validated for all concurrently at the RPC layer, + // but then the pending secret is promoted for one dialer before the others. + // In this scenario the end result of promoting the pending secret is the same, + // but we want to avoid initiating peering streams to all of these clusters. + // Therefore, we accept the first write but reject all others. + return fmt.Errorf("invalid pending stream secret: secret was already promoted") + } + + // Store the newly-generated pending stream secret, overwriting any that existed. + secrets.Stream = &pbpeering.PeeringSecrets_Stream{ + // Promoting a pending secret moves it to active. + PendingSecretID: "", + + // Store the newly-promoted pending secret as the active secret. + ActiveSecretID: r.PromotePending.ActiveStreamSecret, + } + + // Avoid invalidating existing establishment secrets when promoting pending secrets. + secrets.Establishment = existing.GetEstablishment() + + // If there was previously an active stream secret it gets replaced in favor of the pending secret + // that is being promoted. + if existingActive := existing.GetStream().GetActiveSecretID(); existingActive != "" { + toDelete = append(toDelete, existingActive) + } + + case *pbpeering.SecretsWriteRequest_Establish: + // This should never happen. Dialing peers are the only ones that can call Establish, + // and the peering secrets for dialing peers should have been inserted earlier in the function. + return fmt.Errorf("an accepting peer should not have called Establish RPC") + + default: + return fmt.Errorf("got unexpected request type: %T", req.Request) } for _, id := range toDelete { if err := tx.Delete(tablePeeringSecretUUIDs, id); err != nil { @@ -295,7 +351,7 @@ func (s *Store) peeringSecretsWriteTxn(tx WriteTxn, req *pbpeering.PeeringSecret } } - if err := tx.Insert(tablePeeringSecrets, secret); err != nil { + if err := tx.Insert(tablePeeringSecrets, &secrets); err != nil { return fmt.Errorf("failed inserting peering: %w", err) } return nil diff --git a/agent/consul/state/peering_test.go b/agent/consul/state/peering_test.go index 4c0001caf6..37b2a5be2f 100644 --- a/agent/consul/state/peering_test.go +++ b/agent/consul/state/peering_test.go @@ -236,24 +236,45 @@ func TestStore_PeeringSecretsWrite(t *testing.T) { return resp } - writeSeed := func(s *Store, req *pbpeering.PeeringWriteRequest) { + var ( + testSecretOne = testUUID() + testSecretTwo = testUUID() + testSecretThree = testUUID() + testSecretFour = testUUID() + ) + + type testSeed struct { + peering *pbpeering.Peering + secrets *pbpeering.PeeringSecrets + } + + type testcase struct { + name string + seed *testSeed + input *pbpeering.SecretsWriteRequest + expect *pbpeering.PeeringSecrets + expectUUIDs []string + expectErr string + } + + writeSeed := func(s *Store, seed *testSeed) { tx := s.db.WriteTxn(1) defer tx.Abort() - if req.Peering != nil { - require.NoError(t, tx.Insert(tablePeering, req.Peering)) + if seed.peering != nil { + require.NoError(t, tx.Insert(tablePeering, seed.peering)) } - if secretsReq := req.SecretsRequest; secretsReq != nil { - require.NoError(t, tx.Insert(tablePeeringSecrets, secretsReq.Secrets)) + if seed.secrets != nil { + require.NoError(t, tx.Insert(tablePeeringSecrets, seed.secrets)) var toInsert []string - if establishment := secretsReq.Secrets.GetEstablishment().GetSecretID(); establishment != "" { + if establishment := seed.secrets.GetEstablishment().GetSecretID(); establishment != "" { toInsert = append(toInsert, establishment) } - if pending := secretsReq.Secrets.GetStream().GetPendingSecretID(); pending != "" { + if pending := seed.secrets.GetStream().GetPendingSecretID(); pending != "" { toInsert = append(toInsert, pending) } - if active := secretsReq.Secrets.GetStream().GetActiveSecretID(); active != "" { + if active := seed.secrets.GetStream().GetActiveSecretID(); active != "" { toInsert = append(toInsert, active) } for _, id := range toInsert { @@ -264,20 +285,6 @@ func TestStore_PeeringSecretsWrite(t *testing.T) { tx.Commit() } - var ( - testSecretOne = testUUID() - testSecretTwo = testUUID() - testSecretThree = testUUID() - ) - - type testcase struct { - name string - seed *pbpeering.PeeringWriteRequest - input *pbpeering.PeeringSecretsWriteRequest - expect *pbpeering.PeeringSecrets - expectUUIDs []string - expectErr string - } run := func(t *testing.T, tc testcase) { s := NewStateStore(nil) @@ -294,7 +301,7 @@ func TestStore_PeeringSecretsWrite(t *testing.T) { require.NoError(t, err) // Validate that we read what we expect - secrets, err := s.PeeringSecretsRead(nil, tc.input.GetSecrets().GetPeerID()) + secrets, err := s.PeeringSecretsRead(nil, tc.input.GetPeerID()) require.NoError(t, err) require.NotNil(t, secrets) prototest.AssertDeepEqual(t, tc.expect, secrets) @@ -305,46 +312,129 @@ func TestStore_PeeringSecretsWrite(t *testing.T) { tcs := []testcase{ { name: "missing peer id", - input: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{}, + input: &pbpeering.SecretsWriteRequest{ + Request: &pbpeering.SecretsWriteRequest_GenerateToken{}, }, expectErr: "missing peer ID", }, - { - name: "no secret IDs were embedded", - input: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testFooPeerID, - }, - }, - expectErr: "no secret IDs were embedded", - }, { name: "unknown peer id", - input: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testFooPeerID, - Establishment: &pbpeering.PeeringSecrets_Establishment{ - SecretID: testFooSecretID, + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ + EstablishmentSecret: testFooSecretID, }, }, }, expectErr: "unknown peering", }, { - name: "dialing peer does not track UUIDs", - seed: &pbpeering.PeeringWriteRequest{ - Peering: &pbpeering.Peering{ + name: "no secret IDs were embedded when generating token", + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_GenerateToken{}, + }, + expectErr: "missing secret ID", + }, + { + name: "no secret IDs were embedded when establishing peering", + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_Establish{}, + }, + expectErr: "missing secret ID", + }, + { + name: "no secret IDs were embedded when exchanging secret", + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_ExchangeSecret{}, + }, + expectErr: "missing secret ID", + }, + { + name: "no secret IDs were embedded when promoting pending secret", + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_PromotePending{}, + }, + expectErr: "missing secret ID", + }, + { + name: "dialing peer invalid request type - generate token", + seed: &testSeed{ + peering: &pbpeering.Peering{ Name: "foo", ID: testFooPeerID, PeerServerAddresses: []string{"10.0.0.1:5300"}, }, }, - input: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testFooPeerID, - Stream: &pbpeering.PeeringSecrets_Stream{ - ActiveSecretID: testFooSecretID, + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + // Dialing peer must only write secrets from Establish + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ + EstablishmentSecret: testFooSecretID, + }, + }, + }, + expectErr: "invalid request type", + }, + { + name: "dialing peer invalid request type - exchange secret", + seed: &testSeed{ + peering: &pbpeering.Peering{ + Name: "foo", + ID: testFooPeerID, + PeerServerAddresses: []string{"10.0.0.1:5300"}, + }, + }, + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + // Dialing peer must only write secrets from Establish + Request: &pbpeering.SecretsWriteRequest_ExchangeSecret{ + ExchangeSecret: &pbpeering.SecretsWriteRequest_ExchangeSecretRequest{ + PendingStreamSecret: testFooSecretID, + }, + }, + }, + expectErr: "invalid request type", + }, + { + name: "dialing peer invalid request type - promote pending", + seed: &testSeed{ + peering: &pbpeering.Peering{ + Name: "foo", + ID: testFooPeerID, + PeerServerAddresses: []string{"10.0.0.1:5300"}, + }, + }, + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + // Dialing peer must only write secrets from Establish + Request: &pbpeering.SecretsWriteRequest_PromotePending{ + PromotePending: &pbpeering.SecretsWriteRequest_PromotePendingRequest{ + ActiveStreamSecret: testFooSecretID, + }, + }, + }, + expectErr: "invalid request type", + }, + { + name: "dialing peer does not track UUIDs", + seed: &testSeed{ + peering: &pbpeering.Peering{ + Name: "foo", + ID: testFooPeerID, + PeerServerAddresses: []string{"10.0.0.1:5300"}, + }, + }, + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_Establish{ + Establish: &pbpeering.SecretsWriteRequest_EstablishRequest{ + ActiveStreamSecret: testFooSecretID, }, }, }, @@ -357,49 +447,28 @@ func TestStore_PeeringSecretsWrite(t *testing.T) { // UUIDs are only tracked for uniqueness in the generating cluster. expectUUIDs: []string{}, }, - { - name: "unspecified operation", - seed: &pbpeering.PeeringWriteRequest{ - Peering: &pbpeering.Peering{ - Name: "foo", - ID: testFooPeerID, - }, - }, - input: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testFooPeerID, - Establishment: &pbpeering.PeeringSecrets_Establishment{ - SecretID: testFooSecretID, - }, - }, - }, - expectErr: "the operation that triggered the secrets write was not specified", - }, { name: "generate new establishment secret when secrets already existed", - seed: &pbpeering.PeeringWriteRequest{ - Peering: &pbpeering.Peering{ + seed: &testSeed{ + peering: &pbpeering.Peering{ Name: "foo", ID: testFooPeerID, }, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testFooPeerID, - Stream: &pbpeering.PeeringSecrets_Stream{ - PendingSecretID: testSecretOne, - ActiveSecretID: testSecretTwo, - }, + secrets: &pbpeering.PeeringSecrets{ + PeerID: testFooPeerID, + Stream: &pbpeering.PeeringSecrets_Stream{ + PendingSecretID: testSecretOne, + ActiveSecretID: testSecretTwo, }, }, }, - input: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testFooPeerID, - Establishment: &pbpeering.PeeringSecrets_Establishment{ - SecretID: testSecretThree, + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ + EstablishmentSecret: testSecretThree, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_GENERATETOKEN, }, expect: &pbpeering.PeeringSecrets{ PeerID: testFooPeerID, @@ -416,29 +485,26 @@ func TestStore_PeeringSecretsWrite(t *testing.T) { }, { name: "generate new token to replace establishment secret", - seed: &pbpeering.PeeringWriteRequest{ - Peering: &pbpeering.Peering{ + seed: &testSeed{ + peering: &pbpeering.Peering{ Name: "foo", ID: testFooPeerID, }, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testFooPeerID, - Establishment: &pbpeering.PeeringSecrets_Establishment{ - SecretID: testSecretOne, - }, + secrets: &pbpeering.PeeringSecrets{ + PeerID: testFooPeerID, + Establishment: &pbpeering.PeeringSecrets_Establishment{ + SecretID: testSecretOne, }, }, }, - input: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testFooPeerID, - Establishment: &pbpeering.PeeringSecrets_Establishment{ + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ // Two replaces One - SecretID: testSecretTwo, + EstablishmentSecret: testSecretTwo, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_GENERATETOKEN, }, expect: &pbpeering.PeeringSecrets{ PeerID: testFooPeerID, @@ -449,59 +515,110 @@ func TestStore_PeeringSecretsWrite(t *testing.T) { expectUUIDs: []string{testSecretTwo}, }, { - name: "exchange secret to generate new pending secret", - seed: &pbpeering.PeeringWriteRequest{ - Peering: &pbpeering.Peering{ + name: "cannot exchange secret without existing secrets", + seed: &testSeed{ + peering: &pbpeering.Peering{ Name: "foo", ID: testFooPeerID, }, + // Do not seed an establishment secret. }, - input: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_ExchangeSecret{ + ExchangeSecret: &pbpeering.SecretsWriteRequest_ExchangeSecretRequest{ + PendingStreamSecret: testSecretOne, + }, + }, + }, + expectErr: "no known secrets for peering", + }, + { + name: "cannot exchange secret without establishment secret", + seed: &testSeed{ + peering: &pbpeering.Peering{ + Name: "foo", + ID: testFooPeerID, + }, + secrets: &pbpeering.PeeringSecrets{ PeerID: testFooPeerID, Stream: &pbpeering.PeeringSecrets_Stream{ PendingSecretID: testSecretOne, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_EXCHANGESECRET, + }, + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_ExchangeSecret{ + ExchangeSecret: &pbpeering.SecretsWriteRequest_ExchangeSecretRequest{ + // Attempt to replace One with Two + PendingStreamSecret: testSecretTwo, + }, + }, + }, + expectErr: "peering was already established", + }, + { + name: "exchange secret to generate new pending secret", + seed: &testSeed{ + peering: &pbpeering.Peering{ + Name: "foo", + ID: testFooPeerID, + }, + secrets: &pbpeering.PeeringSecrets{ + PeerID: testFooPeerID, + Establishment: &pbpeering.PeeringSecrets_Establishment{ + SecretID: testSecretOne, + }, + }, + }, + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_ExchangeSecret{ + ExchangeSecret: &pbpeering.SecretsWriteRequest_ExchangeSecretRequest{ + PendingStreamSecret: testSecretTwo, + }, + }, }, expect: &pbpeering.PeeringSecrets{ PeerID: testFooPeerID, Stream: &pbpeering.PeeringSecrets_Stream{ - PendingSecretID: testSecretOne, + PendingSecretID: testSecretTwo, }, }, - expectUUIDs: []string{testSecretOne}, + // Establishment secret testSecretOne is discarded when exchanging for a stream secret + expectUUIDs: []string{testSecretTwo}, }, { name: "exchange secret replaces pending stream secret", - seed: &pbpeering.PeeringWriteRequest{ - Peering: &pbpeering.Peering{ + seed: &testSeed{ + peering: &pbpeering.Peering{ Name: "foo", ID: testFooPeerID, }, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testFooPeerID, - Stream: &pbpeering.PeeringSecrets_Stream{ - ActiveSecretID: testSecretOne, - PendingSecretID: testSecretTwo, - }, + secrets: &pbpeering.PeeringSecrets{ + PeerID: testFooPeerID, + Establishment: &pbpeering.PeeringSecrets_Establishment{ + SecretID: testSecretFour, + }, + Stream: &pbpeering.PeeringSecrets_Stream{ + ActiveSecretID: testSecretOne, + PendingSecretID: testSecretTwo, }, }, }, - input: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testFooPeerID, - Stream: &pbpeering.PeeringSecrets_Stream{ + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_ExchangeSecret{ + ExchangeSecret: &pbpeering.SecretsWriteRequest_ExchangeSecretRequest{ // Three replaces two - PendingSecretID: testSecretThree, + PendingStreamSecret: testSecretThree, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_EXCHANGESECRET, }, expect: &pbpeering.PeeringSecrets{ PeerID: testFooPeerID, + // Establishment secret is discarded in favor of new pending secret. Stream: &pbpeering.PeeringSecrets_Stream{ // Active secret is not deleted until the new pending secret is promoted ActiveSecretID: testSecretOne, @@ -511,34 +628,75 @@ func TestStore_PeeringSecretsWrite(t *testing.T) { expectUUIDs: []string{testSecretOne, testSecretThree}, }, { - name: "promote pending secret and delete active", - seed: &pbpeering.PeeringWriteRequest{ - Peering: &pbpeering.Peering{ + name: "cannot promote pending without existing secrets", + seed: &testSeed{ + peering: &pbpeering.Peering{ Name: "foo", ID: testFooPeerID, }, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testFooPeerID, - Establishment: &pbpeering.PeeringSecrets_Establishment{ - SecretID: testSecretThree, - }, - Stream: &pbpeering.PeeringSecrets_Stream{ - PendingSecretID: testSecretTwo, - ActiveSecretID: testSecretOne, - }, + // Do not seed a pending secret. + }, + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_PromotePending{ + PromotePending: &pbpeering.SecretsWriteRequest_PromotePendingRequest{ + ActiveStreamSecret: testSecretOne, }, }, }, - input: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ + expectErr: "no known secrets for peering", + }, + { + name: "cannot promote pending without existing pending secret", + seed: &testSeed{ + peering: &pbpeering.Peering{ + Name: "foo", + ID: testFooPeerID, + }, + secrets: &pbpeering.PeeringSecrets{ PeerID: testFooPeerID, Stream: &pbpeering.PeeringSecrets_Stream{ - // Two gets promoted over One - ActiveSecretID: testSecretTwo, + ActiveSecretID: testSecretOne, + }, + }, + }, + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_PromotePending{ + PromotePending: &pbpeering.SecretsWriteRequest_PromotePendingRequest{ + // Attempt to replace One with Two + ActiveStreamSecret: testSecretTwo, + }, + }, + }, + expectErr: "secret was already promoted", + }, + { + name: "promote pending secret and delete active", + seed: &testSeed{ + peering: &pbpeering.Peering{ + Name: "foo", + ID: testFooPeerID, + }, + secrets: &pbpeering.PeeringSecrets{ + PeerID: testFooPeerID, + Establishment: &pbpeering.PeeringSecrets_Establishment{ + SecretID: testSecretThree, + }, + Stream: &pbpeering.PeeringSecrets_Stream{ + PendingSecretID: testSecretTwo, + ActiveSecretID: testSecretOne, + }, + }, + }, + input: &pbpeering.SecretsWriteRequest{ + PeerID: testFooPeerID, + Request: &pbpeering.SecretsWriteRequest_PromotePending{ + PromotePending: &pbpeering.SecretsWriteRequest_PromotePendingRequest{ + // Two gets promoted over One + ActiveStreamSecret: testSecretTwo, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_PROMOTEPENDING, }, expect: &pbpeering.PeeringSecrets{ PeerID: testFooPeerID, @@ -936,14 +1094,13 @@ func TestStore_PeeringWrite(t *testing.T) { Name: "baz", Partition: structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty(), }, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testBazPeerID, - Establishment: &pbpeering.PeeringSecrets_Establishment{ - SecretID: testBazSecretID, + SecretsRequest: &pbpeering.SecretsWriteRequest{ + PeerID: testBazPeerID, + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ + EstablishmentSecret: testBazSecretID, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_GENERATETOKEN, }, }, expectSecrets: &pbpeering.PeeringSecrets{ diff --git a/agent/grpc-external/services/peerstream/server.go b/agent/grpc-external/services/peerstream/server.go index be397c4b04..7254c60c7c 100644 --- a/agent/grpc-external/services/peerstream/server.go +++ b/agent/grpc-external/services/peerstream/server.go @@ -99,7 +99,7 @@ type Backend interface { GetLeaderAddress() string ValidateProposedPeeringSecret(id string) (bool, error) - PeeringSecretsWrite(req *pbpeering.PeeringSecretsWriteRequest) error + PeeringSecretsWrite(req *pbpeering.SecretsWriteRequest) error PeeringTerminateByID(req *pbpeering.PeeringTerminateByIDRequest) error PeeringTrustBundleWrite(req *pbpeering.PeeringTrustBundleWriteRequest) error CatalogRegister(req *structs.RegisterRequest) error diff --git a/agent/grpc-external/services/peerstream/server_test.go b/agent/grpc-external/services/peerstream/server_test.go index b131993232..a24d8edc2f 100644 --- a/agent/grpc-external/services/peerstream/server_test.go +++ b/agent/grpc-external/services/peerstream/server_test.go @@ -26,12 +26,13 @@ func TestServer_ExchangeSecret(t *testing.T) { var secret string testutil.RunStep(t, "known establishment secret is accepted", func(t *testing.T) { // First write the establishment secret so that it can be exchanged - require.NoError(t, store.PeeringSecretsWrite(1, &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testPeerID, - Establishment: &pbpeering.PeeringSecrets_Establishment{SecretID: testEstablishmentSecretID}, + require.NoError(t, store.PeeringSecretsWrite(1, &pbpeering.SecretsWriteRequest{ + PeerID: testPeerID, + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ + EstablishmentSecret: testEstablishmentSecretID, + }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_GENERATETOKEN, })) // Exchange the now-valid establishment secret for a stream secret diff --git a/agent/grpc-external/services/peerstream/stream_resources.go b/agent/grpc-external/services/peerstream/stream_resources.go index 62e3c5b008..f7321d3eef 100644 --- a/agent/grpc-external/services/peerstream/stream_resources.go +++ b/agent/grpc-external/services/peerstream/stream_resources.go @@ -77,21 +77,14 @@ func (s *Server) ExchangeSecret(ctx context.Context, req *pbpeerstream.ExchangeS return nil, grpcstatus.Errorf(codes.Internal, "failed to generate peering stream secret: %v", err) } - writeReq := &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: req.PeerID, - Stream: &pbpeering.PeeringSecrets_Stream{ - // Overwriting any existing un-utilized pending stream secret. - PendingSecretID: id, - - // If there is an active stream secret ID it is NOT invalidated here. - // It remains active until the pending secret ID is used and promoted to active. - // This allows dialing clusters with the active stream secret to continue to dial successfully until they - // receive the new secret. - ActiveSecretID: existing.GetStream().GetActiveSecretID(), + writeReq := &pbpeering.SecretsWriteRequest{ + PeerID: req.PeerID, + Request: &pbpeering.SecretsWriteRequest_ExchangeSecret{ + ExchangeSecret: &pbpeering.SecretsWriteRequest_ExchangeSecretRequest{ + // Overwrite any existing un-utilized pending stream secret. + PendingStreamSecret: id, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_EXCHANGESECRET, } err = s.Backend.PeeringSecretsWrite(writeReq) if err != nil { @@ -194,18 +187,14 @@ func (s *Server) StreamResources(stream pbpeerstream.PeerStreamService_StreamRes } authorized = true - promoted := &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: req.PeerID, - Stream: &pbpeering.PeeringSecrets_Stream{ - ActiveSecretID: pending, - - // The PendingSecretID is intentionally zeroed out since we want to avoid re-triggering this - // promotion process with the same pending secret. - PendingSecretID: "", + promoted := &pbpeering.SecretsWriteRequest{ + PeerID: p.ID, + Request: &pbpeering.SecretsWriteRequest_PromotePending{ + PromotePending: &pbpeering.SecretsWriteRequest_PromotePendingRequest{ + // Overwrite any existing un-utilized pending stream secret. + ActiveStreamSecret: pending, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_PROMOTEPENDING, } err = s.Backend.PeeringSecretsWrite(promoted) if err != nil { diff --git a/agent/grpc-external/services/peerstream/stream_test.go b/agent/grpc-external/services/peerstream/stream_test.go index 3ba293069e..309d7c12c6 100644 --- a/agent/grpc-external/services/peerstream/stream_test.go +++ b/agent/grpc-external/services/peerstream/stream_test.go @@ -181,9 +181,13 @@ func TestStreamResources_Server_LeaderBecomesFollower(t *testing.T) { } func TestStreamResources_Server_ActiveSecretValidation(t *testing.T) { + type testSeed struct { + peering *pbpeering.Peering + secrets []*pbpeering.SecretsWriteRequest + } type testCase struct { name string - seed *pbpeering.PeeringWriteRequest + seed *testSeed input *pbpeerstream.ReplicationMessage wantErr error } @@ -194,7 +198,13 @@ func TestStreamResources_Server_ActiveSecretValidation(t *testing.T) { srv, store := newTestServer(t, nil) // Write a seed peering. - require.NoError(t, store.PeeringWrite(1, tc.seed)) + if tc.seed != nil { + require.NoError(t, store.PeeringWrite(1, &pbpeering.PeeringWriteRequest{Peering: tc.seed.peering})) + + for _, s := range tc.seed.secrets { + require.NoError(t, store.PeeringSecretsWrite(1, s)) + } + } // Set the initial roots and CA configuration. _, _ = writeInitialRootsAndCA(t, store) @@ -223,12 +233,14 @@ func TestStreamResources_Server_ActiveSecretValidation(t *testing.T) { } else { require.NoError(t, err) } + + client.Close() } tt := []testCase{ { name: "no secret for peering", - seed: &pbpeering.PeeringWriteRequest{ - Peering: &pbpeering.Peering{ + seed: &testSeed{ + peering: &pbpeering.Peering{ Name: "foo", ID: peeringWithoutSecrets, }, @@ -244,19 +256,20 @@ func TestStreamResources_Server_ActiveSecretValidation(t *testing.T) { }, { name: "unknown secret", - seed: &pbpeering.PeeringWriteRequest{ - Peering: &pbpeering.Peering{ + seed: &testSeed{ + peering: &pbpeering.Peering{ Name: "foo", ID: testPeerID, }, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ + secrets: []*pbpeering.SecretsWriteRequest{ + { PeerID: testPeerID, - Stream: &pbpeering.PeeringSecrets_Stream{ - ActiveSecretID: testActiveStreamSecretID, + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ + EstablishmentSecret: testEstablishmentSecretID, + }, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_PROMOTEPENDING, }, }, input: &pbpeerstream.ReplicationMessage{ @@ -270,46 +283,73 @@ func TestStreamResources_Server_ActiveSecretValidation(t *testing.T) { wantErr: status.Error(codes.PermissionDenied, "invalid peering stream secret"), }, { - name: "known active secret", - seed: &pbpeering.PeeringWriteRequest{ - Peering: &pbpeering.Peering{ + name: "known pending secret", + seed: &testSeed{ + peering: &pbpeering.Peering{ Name: "foo", ID: testPeerID, }, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ + secrets: []*pbpeering.SecretsWriteRequest{ + { PeerID: testPeerID, - Stream: &pbpeering.PeeringSecrets_Stream{ - ActiveSecretID: testActiveStreamSecretID, + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ + EstablishmentSecret: testEstablishmentSecretID, + }, + }, + }, + { + PeerID: testPeerID, + Request: &pbpeering.SecretsWriteRequest_ExchangeSecret{ + ExchangeSecret: &pbpeering.SecretsWriteRequest_ExchangeSecretRequest{ + PendingStreamSecret: testPendingStreamSecretID, + }, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_PROMOTEPENDING, }, }, input: &pbpeerstream.ReplicationMessage{ Payload: &pbpeerstream.ReplicationMessage_Open_{ Open: &pbpeerstream.ReplicationMessage_Open{ PeerID: testPeerID, - StreamSecretID: testActiveStreamSecretID, + StreamSecretID: testPendingStreamSecretID, }, }, }, }, { - name: "known pending secret", - seed: &pbpeering.PeeringWriteRequest{ - Peering: &pbpeering.Peering{ + name: "known active secret", + seed: &testSeed{ + peering: &pbpeering.Peering{ Name: "foo", ID: testPeerID, }, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ + secrets: []*pbpeering.SecretsWriteRequest{ + { PeerID: testPeerID, - Stream: &pbpeering.PeeringSecrets_Stream{ - PendingSecretID: testPendingStreamSecretID, + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ + EstablishmentSecret: testEstablishmentSecretID, + }, + }, + }, + { + PeerID: testPeerID, + Request: &pbpeering.SecretsWriteRequest_ExchangeSecret{ + ExchangeSecret: &pbpeering.SecretsWriteRequest_ExchangeSecretRequest{ + PendingStreamSecret: testPendingStreamSecretID, + }, + }, + }, + { + PeerID: testPeerID, + Request: &pbpeering.SecretsWriteRequest_PromotePending{ + PromotePending: &pbpeering.SecretsWriteRequest_PromotePendingRequest{ + // Pending gets promoted to active. + ActiveStreamSecret: testPendingStreamSecretID, + }, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_EXCHANGESECRET, }, }, input: &pbpeerstream.ReplicationMessage{ @@ -1399,7 +1439,7 @@ func (b *testStreamBackend) ValidateProposedPeeringSecret(id string) (bool, erro return true, nil } -func (b *testStreamBackend) PeeringSecretsWrite(req *pbpeering.PeeringSecretsWriteRequest) error { +func (b *testStreamBackend) PeeringSecretsWrite(req *pbpeering.SecretsWriteRequest) error { return b.store.PeeringSecretsWrite(1, req) } @@ -1640,16 +1680,25 @@ func writeTestPeering(t *testing.T, store *state.Store, idx uint64, peerName, re if remotePeerID != "" { peering.PeerServerAddresses = []string{"127.0.0.1:5300"} } + require.NoError(t, store.PeeringWrite(idx, &pbpeering.PeeringWriteRequest{ Peering: &peering, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: testPeerID, - Stream: &pbpeering.PeeringSecrets_Stream{ - PendingSecretID: testPendingStreamSecretID, + SecretsRequest: &pbpeering.SecretsWriteRequest{ + PeerID: testPeerID, + // Simulate generating a stream secret by first generating a token then exchanging for a stream secret. + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ + EstablishmentSecret: testEstablishmentSecretID, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_EXCHANGESECRET, + }, + })) + require.NoError(t, store.PeeringSecretsWrite(idx, &pbpeering.SecretsWriteRequest{ + PeerID: testPeerID, + Request: &pbpeering.SecretsWriteRequest_ExchangeSecret{ + ExchangeSecret: &pbpeering.SecretsWriteRequest_ExchangeSecretRequest{ + PendingStreamSecret: testPendingStreamSecretID, + }, }, })) diff --git a/agent/rpc/peering/service.go b/agent/rpc/peering/service.go index 4e23ee818b..ed9cd9e4fa 100644 --- a/agent/rpc/peering/service.go +++ b/agent/rpc/peering/service.go @@ -260,14 +260,13 @@ func (s *Server) GenerateToken( writeReq := &pbpeering.PeeringWriteRequest{ Peering: peering, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: peering.ID, - Establishment: &pbpeering.PeeringSecrets_Establishment{ - SecretID: secretID, + SecretsRequest: &pbpeering.SecretsWriteRequest{ + PeerID: peering.ID, + Request: &pbpeering.SecretsWriteRequest_GenerateToken{ + GenerateToken: &pbpeering.SecretsWriteRequest_GenerateTokenRequest{ + EstablishmentSecret: secretID, }, }, - Operation: pbpeering.PeeringSecretsWriteRequest_OPERATION_GENERATETOKEN, }, } if err := s.Backend.PeeringWrite(writeReq); err != nil { @@ -434,19 +433,19 @@ func (s *Server) Establish( return nil, dialErrors } - // As soon as a peering is written with a list of ServerAddresses that is - // non-empty, the leader routine will see the peering and attempt to - // establish a connection with the remote peer. + // As soon as a peering is written with a non-empty list of ServerAddresses + // and an active stream secret, a leader routine will see the peering and + // attempt to establish a peering stream with the remote peer. // // This peer now has a record of both the LocalPeerID(ID) and // RemotePeerID(PeerID) but at this point the other peer does not. writeReq := &pbpeering.PeeringWriteRequest{ Peering: peering, - SecretsRequest: &pbpeering.PeeringSecretsWriteRequest{ - Secrets: &pbpeering.PeeringSecrets{ - PeerID: peering.ID, - Stream: &pbpeering.PeeringSecrets_Stream{ - ActiveSecretID: exchangeResp.StreamSecret, + SecretsRequest: &pbpeering.SecretsWriteRequest{ + PeerID: peering.ID, + Request: &pbpeering.SecretsWriteRequest_Establish{ + Establish: &pbpeering.SecretsWriteRequest_EstablishRequest{ + ActiveStreamSecret: exchangeResp.StreamSecret, }, }, }, diff --git a/proto/pbpeering/peering.go b/proto/pbpeering/peering.go index 172857b1c2..d31328b589 100644 --- a/proto/pbpeering/peering.go +++ b/proto/pbpeering/peering.go @@ -155,17 +155,32 @@ func (p *Peering) IsActive() bool { } // Validate is a validation helper that checks whether a secret ID is embedded in the container type. -func (p *PeeringSecrets) Validate() error { - if p.GetPeerID() == "" { +func (s *SecretsWriteRequest) Validate() error { + if s.PeerID == "" { return errors.New("missing peer ID") } - if p.GetEstablishment().GetSecretID() != "" { - return nil + switch r := s.Request.(type) { + case *SecretsWriteRequest_GenerateToken: + if r != nil && r.GenerateToken.GetEstablishmentSecret() != "" { + return nil + } + case *SecretsWriteRequest_Establish: + if r != nil && r.Establish.GetActiveStreamSecret() != "" { + return nil + } + case *SecretsWriteRequest_ExchangeSecret: + if r != nil && r.ExchangeSecret.GetPendingStreamSecret() != "" { + return nil + } + case *SecretsWriteRequest_PromotePending: + if r != nil && r.PromotePending.GetActiveStreamSecret() != "" { + return nil + } + default: + return fmt.Errorf("unexpected request type %T", s.Request) } - if p.GetStream().GetPendingSecretID() != "" || p.GetStream().GetActiveSecretID() != "" { - return nil - } - return errors.New("no secret IDs were embedded") + + return errors.New("missing secret ID") } // TLSDialOption returns the gRPC DialOption to secure the transport if CAPems diff --git a/proto/pbpeering/peering.pb.binary.go b/proto/pbpeering/peering.pb.binary.go index 2e228ccc3f..2e9d5c71cc 100644 --- a/proto/pbpeering/peering.pb.binary.go +++ b/proto/pbpeering/peering.pb.binary.go @@ -8,12 +8,52 @@ import ( ) // MarshalBinary implements encoding.BinaryMarshaler -func (msg *PeeringSecretsWriteRequest) MarshalBinary() ([]byte, error) { +func (msg *SecretsWriteRequest) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) } // UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *PeeringSecretsWriteRequest) UnmarshalBinary(b []byte) error { +func (msg *SecretsWriteRequest) UnmarshalBinary(b []byte) error { + return proto.Unmarshal(b, msg) +} + +// MarshalBinary implements encoding.BinaryMarshaler +func (msg *SecretsWriteRequest_GenerateTokenRequest) MarshalBinary() ([]byte, error) { + return proto.Marshal(msg) +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler +func (msg *SecretsWriteRequest_GenerateTokenRequest) UnmarshalBinary(b []byte) error { + return proto.Unmarshal(b, msg) +} + +// MarshalBinary implements encoding.BinaryMarshaler +func (msg *SecretsWriteRequest_ExchangeSecretRequest) MarshalBinary() ([]byte, error) { + return proto.Marshal(msg) +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler +func (msg *SecretsWriteRequest_ExchangeSecretRequest) UnmarshalBinary(b []byte) error { + return proto.Unmarshal(b, msg) +} + +// MarshalBinary implements encoding.BinaryMarshaler +func (msg *SecretsWriteRequest_PromotePendingRequest) MarshalBinary() ([]byte, error) { + return proto.Marshal(msg) +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler +func (msg *SecretsWriteRequest_PromotePendingRequest) UnmarshalBinary(b []byte) error { + return proto.Unmarshal(b, msg) +} + +// MarshalBinary implements encoding.BinaryMarshaler +func (msg *SecretsWriteRequest_EstablishRequest) MarshalBinary() ([]byte, error) { + return proto.Marshal(msg) +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler +func (msg *SecretsWriteRequest_EstablishRequest) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } diff --git a/proto/pbpeering/peering.pb.go b/proto/pbpeering/peering.pb.go index 70ef3ab4aa..5d061913bf 100644 --- a/proto/pbpeering/peering.pb.go +++ b/proto/pbpeering/peering.pb.go @@ -96,71 +96,26 @@ func (PeeringState) EnumDescriptor() ([]byte, []int) { return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{0} } -type PeeringSecretsWriteRequest_Operation int32 - -const ( - PeeringSecretsWriteRequest_OPERATION_UNSPECIFIED PeeringSecretsWriteRequest_Operation = 0 - PeeringSecretsWriteRequest_OPERATION_GENERATETOKEN PeeringSecretsWriteRequest_Operation = 1 - PeeringSecretsWriteRequest_OPERATION_EXCHANGESECRET PeeringSecretsWriteRequest_Operation = 2 - PeeringSecretsWriteRequest_OPERATION_PROMOTEPENDING PeeringSecretsWriteRequest_Operation = 3 -) - -// Enum value maps for PeeringSecretsWriteRequest_Operation. -var ( - PeeringSecretsWriteRequest_Operation_name = map[int32]string{ - 0: "OPERATION_UNSPECIFIED", - 1: "OPERATION_GENERATETOKEN", - 2: "OPERATION_EXCHANGESECRET", - 3: "OPERATION_PROMOTEPENDING", - } - PeeringSecretsWriteRequest_Operation_value = map[string]int32{ - "OPERATION_UNSPECIFIED": 0, - "OPERATION_GENERATETOKEN": 1, - "OPERATION_EXCHANGESECRET": 2, - "OPERATION_PROMOTEPENDING": 3, - } -) - -func (x PeeringSecretsWriteRequest_Operation) Enum() *PeeringSecretsWriteRequest_Operation { - p := new(PeeringSecretsWriteRequest_Operation) - *p = x - return p -} - -func (x PeeringSecretsWriteRequest_Operation) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (PeeringSecretsWriteRequest_Operation) Descriptor() protoreflect.EnumDescriptor { - return file_proto_pbpeering_peering_proto_enumTypes[1].Descriptor() -} - -func (PeeringSecretsWriteRequest_Operation) Type() protoreflect.EnumType { - return &file_proto_pbpeering_peering_proto_enumTypes[1] -} - -func (x PeeringSecretsWriteRequest_Operation) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use PeeringSecretsWriteRequest_Operation.Descriptor instead. -func (PeeringSecretsWriteRequest_Operation) EnumDescriptor() ([]byte, []int) { - return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{0, 0} -} - -type PeeringSecretsWriteRequest struct { +// SecretsWriteRequest encodes a request to write a peering secret as the result +// of some operation. Different operations, such as generating a peering token, +// lead to modifying the known secrets associated with a peering. +type SecretsWriteRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Secret contains the peering secrets to write. - Secrets *PeeringSecrets `protobuf:"bytes,1,opt,name=secrets,proto3" json:"secrets,omitempty"` - // Operation defines which action triggered the secrets write. - Operation PeeringSecretsWriteRequest_Operation `protobuf:"varint,2,opt,name=operation,proto3,enum=hashicorp.consul.internal.peering.PeeringSecretsWriteRequest_Operation" json:"operation,omitempty"` + // PeerID is the local UUID of the peering this request applies to. + PeerID string `protobuf:"bytes,1,opt,name=PeerID,proto3" json:"PeerID,omitempty"` + // Types that are assignable to Request: + // *SecretsWriteRequest_GenerateToken + // *SecretsWriteRequest_ExchangeSecret + // *SecretsWriteRequest_PromotePending + // *SecretsWriteRequest_Establish + Request isSecretsWriteRequest_Request `protobuf_oneof:"Request"` } -func (x *PeeringSecretsWriteRequest) Reset() { - *x = PeeringSecretsWriteRequest{} +func (x *SecretsWriteRequest) Reset() { + *x = SecretsWriteRequest{} if protoimpl.UnsafeEnabled { mi := &file_proto_pbpeering_peering_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -168,13 +123,13 @@ func (x *PeeringSecretsWriteRequest) Reset() { } } -func (x *PeeringSecretsWriteRequest) String() string { +func (x *SecretsWriteRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PeeringSecretsWriteRequest) ProtoMessage() {} +func (*SecretsWriteRequest) ProtoMessage() {} -func (x *PeeringSecretsWriteRequest) ProtoReflect() protoreflect.Message { +func (x *SecretsWriteRequest) ProtoReflect() protoreflect.Message { mi := &file_proto_pbpeering_peering_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -186,25 +141,81 @@ func (x *PeeringSecretsWriteRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PeeringSecretsWriteRequest.ProtoReflect.Descriptor instead. -func (*PeeringSecretsWriteRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use SecretsWriteRequest.ProtoReflect.Descriptor instead. +func (*SecretsWriteRequest) Descriptor() ([]byte, []int) { return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{0} } -func (x *PeeringSecretsWriteRequest) GetSecrets() *PeeringSecrets { +func (x *SecretsWriteRequest) GetPeerID() string { if x != nil { - return x.Secrets + return x.PeerID + } + return "" +} + +func (m *SecretsWriteRequest) GetRequest() isSecretsWriteRequest_Request { + if m != nil { + return m.Request } return nil } -func (x *PeeringSecretsWriteRequest) GetOperation() PeeringSecretsWriteRequest_Operation { - if x != nil { - return x.Operation +func (x *SecretsWriteRequest) GetGenerateToken() *SecretsWriteRequest_GenerateTokenRequest { + if x, ok := x.GetRequest().(*SecretsWriteRequest_GenerateToken); ok { + return x.GenerateToken } - return PeeringSecretsWriteRequest_OPERATION_UNSPECIFIED + return nil } +func (x *SecretsWriteRequest) GetExchangeSecret() *SecretsWriteRequest_ExchangeSecretRequest { + if x, ok := x.GetRequest().(*SecretsWriteRequest_ExchangeSecret); ok { + return x.ExchangeSecret + } + return nil +} + +func (x *SecretsWriteRequest) GetPromotePending() *SecretsWriteRequest_PromotePendingRequest { + if x, ok := x.GetRequest().(*SecretsWriteRequest_PromotePending); ok { + return x.PromotePending + } + return nil +} + +func (x *SecretsWriteRequest) GetEstablish() *SecretsWriteRequest_EstablishRequest { + if x, ok := x.GetRequest().(*SecretsWriteRequest_Establish); ok { + return x.Establish + } + return nil +} + +type isSecretsWriteRequest_Request interface { + isSecretsWriteRequest_Request() +} + +type SecretsWriteRequest_GenerateToken struct { + GenerateToken *SecretsWriteRequest_GenerateTokenRequest `protobuf:"bytes,2,opt,name=generate_token,json=generateToken,proto3,oneof"` +} + +type SecretsWriteRequest_ExchangeSecret struct { + ExchangeSecret *SecretsWriteRequest_ExchangeSecretRequest `protobuf:"bytes,3,opt,name=exchange_secret,json=exchangeSecret,proto3,oneof"` +} + +type SecretsWriteRequest_PromotePending struct { + PromotePending *SecretsWriteRequest_PromotePendingRequest `protobuf:"bytes,4,opt,name=promote_pending,json=promotePending,proto3,oneof"` +} + +type SecretsWriteRequest_Establish struct { + Establish *SecretsWriteRequest_EstablishRequest `protobuf:"bytes,5,opt,name=establish,proto3,oneof"` +} + +func (*SecretsWriteRequest_GenerateToken) isSecretsWriteRequest_Request() {} + +func (*SecretsWriteRequest_ExchangeSecret) isSecretsWriteRequest_Request() {} + +func (*SecretsWriteRequest_PromotePending) isSecretsWriteRequest_Request() {} + +func (*SecretsWriteRequest_Establish) isSecretsWriteRequest_Request() {} + // PeeringSecrets defines a secret used for authenticating/authorizing peer clusters. type PeeringSecrets struct { state protoimpl.MessageState @@ -762,11 +773,11 @@ type PeeringWriteRequest struct { // Peering is the peering to write with the request. Peering *Peering `protobuf:"bytes,1,opt,name=Peering,proto3" json:"Peering,omitempty"` - // Secret contains the optional peering secrets to persist + // SecretsWriteRequest contains the optional peering secrets to persist // with the peering. Peering secrets are not embedded in the peering // object to avoid leaking them. - SecretsRequest *PeeringSecretsWriteRequest `protobuf:"bytes,2,opt,name=SecretsRequest,proto3" json:"SecretsRequest,omitempty"` - Meta map[string]string `protobuf:"bytes,3,rep,name=Meta,proto3" json:"Meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + SecretsRequest *SecretsWriteRequest `protobuf:"bytes,2,opt,name=SecretsRequest,proto3" json:"SecretsRequest,omitempty"` + Meta map[string]string `protobuf:"bytes,3,rep,name=Meta,proto3" json:"Meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *PeeringWriteRequest) Reset() { @@ -808,7 +819,7 @@ func (x *PeeringWriteRequest) GetPeering() *Peering { return nil } -func (x *PeeringWriteRequest) GetSecretsRequest() *PeeringSecretsWriteRequest { +func (x *PeeringWriteRequest) GetSecretsRequest() *SecretsWriteRequest { if x != nil { return x.SecretsRequest } @@ -1713,6 +1724,213 @@ func (*EstablishResponse) Descriptor() ([]byte, []int) { return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{25} } +// GenerateTokenRequest encodes a request to persist a peering establishment +// secret. It is triggered by generating a new peering token for a peer cluster. +type SecretsWriteRequest_GenerateTokenRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // establishment_secret is the proposed secret ID to store as the establishment + // secret for this peering. + EstablishmentSecret string `protobuf:"bytes,1,opt,name=establishment_secret,json=establishmentSecret,proto3" json:"establishment_secret,omitempty"` +} + +func (x *SecretsWriteRequest_GenerateTokenRequest) Reset() { + *x = SecretsWriteRequest_GenerateTokenRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_pbpeering_peering_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SecretsWriteRequest_GenerateTokenRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SecretsWriteRequest_GenerateTokenRequest) ProtoMessage() {} + +func (x *SecretsWriteRequest_GenerateTokenRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_pbpeering_peering_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SecretsWriteRequest_GenerateTokenRequest.ProtoReflect.Descriptor instead. +func (*SecretsWriteRequest_GenerateTokenRequest) Descriptor() ([]byte, []int) { + return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *SecretsWriteRequest_GenerateTokenRequest) GetEstablishmentSecret() string { + if x != nil { + return x.EstablishmentSecret + } + return "" +} + +// ExchangeSecretRequest encodes a request to persist a pending stream secret +// secret. It is triggered by an acceptor peer generating a long-lived stream secret +// in exchange for an establishment secret. +type SecretsWriteRequest_ExchangeSecretRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // pending_stream_secret is the proposed secret ID to store as the pending stream + // secret for this peering. + PendingStreamSecret string `protobuf:"bytes,1,opt,name=pending_stream_secret,json=pendingStreamSecret,proto3" json:"pending_stream_secret,omitempty"` +} + +func (x *SecretsWriteRequest_ExchangeSecretRequest) Reset() { + *x = SecretsWriteRequest_ExchangeSecretRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_pbpeering_peering_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SecretsWriteRequest_ExchangeSecretRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SecretsWriteRequest_ExchangeSecretRequest) ProtoMessage() {} + +func (x *SecretsWriteRequest_ExchangeSecretRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_pbpeering_peering_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SecretsWriteRequest_ExchangeSecretRequest.ProtoReflect.Descriptor instead. +func (*SecretsWriteRequest_ExchangeSecretRequest) Descriptor() ([]byte, []int) { + return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *SecretsWriteRequest_ExchangeSecretRequest) GetPendingStreamSecret() string { + if x != nil { + return x.PendingStreamSecret + } + return "" +} + +// PromotePendingRequest encodes a request to promote a pending stream secret +// to be an active stream secret. It is triggered when the accepting stream handler +// validates an Open request from a peer with a pending stream secret. +type SecretsWriteRequest_PromotePendingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // active_stream_secret is the proposed secret ID to store as the active stream + // secret for this peering. + ActiveStreamSecret string `protobuf:"bytes,1,opt,name=active_stream_secret,json=activeStreamSecret,proto3" json:"active_stream_secret,omitempty"` +} + +func (x *SecretsWriteRequest_PromotePendingRequest) Reset() { + *x = SecretsWriteRequest_PromotePendingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_pbpeering_peering_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SecretsWriteRequest_PromotePendingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SecretsWriteRequest_PromotePendingRequest) ProtoMessage() {} + +func (x *SecretsWriteRequest_PromotePendingRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_pbpeering_peering_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SecretsWriteRequest_PromotePendingRequest.ProtoReflect.Descriptor instead. +func (*SecretsWriteRequest_PromotePendingRequest) Descriptor() ([]byte, []int) { + return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{0, 2} +} + +func (x *SecretsWriteRequest_PromotePendingRequest) GetActiveStreamSecret() string { + if x != nil { + return x.ActiveStreamSecret + } + return "" +} + +// EstablishRequest encodes a request to persist an active stream secret. +// It is triggered after a dialing peer exchanges their establishment secret +// for a long-lived active stream secret. +type SecretsWriteRequest_EstablishRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // active_stream_secret is the proposed secret ID to store as the active stream + // secret for this peering. + ActiveStreamSecret string `protobuf:"bytes,1,opt,name=active_stream_secret,json=activeStreamSecret,proto3" json:"active_stream_secret,omitempty"` +} + +func (x *SecretsWriteRequest_EstablishRequest) Reset() { + *x = SecretsWriteRequest_EstablishRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_pbpeering_peering_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SecretsWriteRequest_EstablishRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SecretsWriteRequest_EstablishRequest) ProtoMessage() {} + +func (x *SecretsWriteRequest_EstablishRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_pbpeering_peering_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SecretsWriteRequest_EstablishRequest.ProtoReflect.Descriptor instead. +func (*SecretsWriteRequest_EstablishRequest) Descriptor() ([]byte, []int) { + return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{0, 3} +} + +func (x *SecretsWriteRequest_EstablishRequest) GetActiveStreamSecret() string { + if x != nil { + return x.ActiveStreamSecret + } + return "" +} + type PeeringSecrets_Establishment struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1725,7 +1943,7 @@ type PeeringSecrets_Establishment struct { func (x *PeeringSecrets_Establishment) Reset() { *x = PeeringSecrets_Establishment{} if protoimpl.UnsafeEnabled { - mi := &file_proto_pbpeering_peering_proto_msgTypes[26] + mi := &file_proto_pbpeering_peering_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1738,7 +1956,7 @@ func (x *PeeringSecrets_Establishment) String() string { func (*PeeringSecrets_Establishment) ProtoMessage() {} func (x *PeeringSecrets_Establishment) ProtoReflect() protoreflect.Message { - mi := &file_proto_pbpeering_peering_proto_msgTypes[26] + mi := &file_proto_pbpeering_peering_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1784,7 +2002,7 @@ type PeeringSecrets_Stream struct { func (x *PeeringSecrets_Stream) Reset() { *x = PeeringSecrets_Stream{} if protoimpl.UnsafeEnabled { - mi := &file_proto_pbpeering_peering_proto_msgTypes[27] + mi := &file_proto_pbpeering_peering_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1797,7 +2015,7 @@ func (x *PeeringSecrets_Stream) String() string { func (*PeeringSecrets_Stream) ProtoMessage() {} func (x *PeeringSecrets_Stream) ProtoReflect() protoreflect.Message { - mi := &file_proto_pbpeering_peering_proto_msgTypes[27] + mi := &file_proto_pbpeering_peering_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1836,342 +2054,372 @@ var file_proto_pbpeering_peering_proto_rawDesc = []byte{ 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0xd1, 0x02, 0x0a, 0x1a, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, - 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, - 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, - 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, - 0x65, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x47, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x74, 0x6f, 0x22, 0xb2, 0x06, 0x0a, 0x13, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x57, + 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x50, + 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x50, 0x65, 0x65, + 0x72, 0x49, 0x44, 0x12, 0x74, 0x0a, 0x0e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4b, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x77, 0x0a, 0x0f, 0x65, 0x78, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, - 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x73, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7f, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x15, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, - 0x0a, 0x17, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x45, 0x4e, 0x45, - 0x52, 0x41, 0x54, 0x45, 0x54, 0x4f, 0x4b, 0x45, 0x4e, 0x10, 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x4f, - 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x58, 0x43, 0x48, 0x41, 0x4e, 0x47, - 0x45, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x4f, 0x50, 0x45, - 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x4d, 0x4f, 0x54, 0x45, 0x50, 0x45, - 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x22, 0xea, 0x02, 0x0a, 0x0e, 0x50, 0x65, 0x65, 0x72, - 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x65, - 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x50, 0x65, 0x65, 0x72, - 0x49, 0x44, 0x12, 0x65, 0x0a, 0x0d, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x6d, - 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, - 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x2e, 0x45, 0x73, 0x74, - 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0d, 0x65, 0x73, 0x74, 0x61, - 0x62, 0x6c, 0x69, 0x73, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x50, 0x0a, 0x06, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, - 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x2e, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x1a, 0x2b, 0x0a, 0x0d, 0x45, - 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x44, 0x1a, 0x5a, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x12, 0x26, 0x0a, 0x0e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x41, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x44, 0x12, 0x28, 0x0a, 0x0f, 0x50, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x44, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0f, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x49, 0x44, 0x22, 0x8d, 0x05, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, - 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, - 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x48, 0x0a, 0x04, - 0x4d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x57, 0x72, + 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x78, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x48, 0x00, 0x52, 0x0e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x12, 0x77, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x70, 0x65, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x70, 0x72, 0x6f, + 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x67, 0x0a, 0x09, 0x65, + 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x47, + 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x09, 0x65, 0x73, 0x74, 0x61, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x1a, 0x49, 0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x14, + 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, 0x73, 0x74, 0x61, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, + 0x4b, 0x0a, 0x15, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x49, 0x0a, 0x15, + 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x1a, 0x44, 0x0a, 0x10, 0x45, 0x73, 0x74, 0x61, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x42, 0x09, 0x0a, + 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xea, 0x02, 0x0a, 0x0e, 0x50, 0x65, 0x65, + 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x50, + 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x50, 0x65, 0x65, + 0x72, 0x49, 0x44, 0x12, 0x65, 0x0a, 0x0d, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, - 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x45, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, - 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x50, - 0x65, 0x65, 0x72, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x65, 0x65, 0x72, 0x43, 0x41, 0x50, - 0x65, 0x6d, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x50, 0x65, 0x65, 0x72, 0x43, - 0x41, 0x50, 0x65, 0x6d, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x50, 0x65, 0x65, 0x72, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x50, - 0x65, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, - 0x13, 0x50, 0x65, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x50, 0x65, 0x65, 0x72, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, - 0x32, 0x0a, 0x14, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x49, - 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x14, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x14, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x6f, 0x64, - 0x69, 0x66, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, - 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x37, 0x0a, 0x09, 0x4d, - 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, - 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x54, 0x72, 0x75, 0x73, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1a, 0x0a, - 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, - 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x6f, 0x6f, 0x74, 0x50, - 0x45, 0x4d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x52, 0x6f, 0x6f, 0x74, 0x50, - 0x45, 0x4d, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x50, - 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, - 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, - 0x64, 0x65, 0x78, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x49, 0x6e, 0x64, - 0x65, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, - 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x46, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5b, 0x0a, - 0x13, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, - 0x67, 0x52, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x32, 0x0a, 0x12, 0x50, 0x65, - 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5d, - 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, - 0x69, 0x6e, 0x67, 0x52, 0x08, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xd1, 0x02, - 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x2e, 0x45, 0x73, + 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0d, 0x65, 0x73, 0x74, + 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x50, 0x0a, 0x06, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x2e, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x1a, 0x2b, 0x0a, 0x0d, + 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x44, 0x1a, 0x5a, 0x0a, 0x06, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x12, 0x26, 0x0a, 0x0e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x44, 0x12, 0x28, 0x0a, 0x0f, 0x50, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x49, 0x44, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x49, 0x44, 0x22, 0x8d, 0x05, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, + 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x48, 0x0a, + 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x45, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x50, 0x65, 0x65, 0x72, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x65, 0x65, 0x72, 0x43, 0x41, + 0x50, 0x65, 0x6d, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x50, 0x65, 0x65, 0x72, + 0x43, 0x41, 0x50, 0x65, 0x6d, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x50, 0x65, 0x65, 0x72, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x50, 0x65, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x30, + 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x50, 0x65, 0x65, + 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, + 0x12, 0x32, 0x0a, 0x14, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, + 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x14, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x14, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x6f, + 0x64, 0x69, 0x66, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0b, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x37, 0x0a, 0x09, + 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x54, 0x72, 0x75, 0x73, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x54, 0x72, 0x75, 0x73, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1a, + 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, + 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, + 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x6f, 0x6f, 0x74, + 0x50, 0x45, 0x4d, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x52, 0x6f, 0x6f, 0x74, + 0x50, 0x45, 0x4d, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x4d, 0x6f, 0x64, 0x69, 0x66, + 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x46, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5b, + 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x65, 0x0a, 0x0e, 0x53, - 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, - 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, - 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x52, 0x0e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x54, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x16, 0x0a, 0x14, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x48, 0x0a, 0x14, 0x50, 0x65, 0x65, - 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0x17, 0x0a, 0x15, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x93, 0x01, 0x0a, - 0x1f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4b, 0x69, - 0x6e, 0x64, 0x22, 0x89, 0x01, 0x0a, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x4f, 0x0a, - 0x07, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, - 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x07, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x22, 0x4a, - 0x0a, 0x16, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7e, 0x0a, 0x17, 0x54, 0x72, - 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x4d, 0x0a, 0x06, 0x42, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x52, 0x06, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x22, 0x2d, 0x0a, 0x1b, 0x50, 0x65, - 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x42, 0x79, - 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x22, 0x1e, 0x0a, 0x1c, 0x50, 0x65, 0x65, - 0x72, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x42, 0x79, 0x49, - 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x1e, 0x50, 0x65, - 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, - 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x65, 0x0a, 0x12, - 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x6e, 0x67, 0x52, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x32, 0x0a, 0x12, 0x50, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x5d, 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, + 0x72, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xca, + 0x02, 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x5e, 0x0a, 0x0e, + 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, + 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0e, 0x53, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x04, + 0x4d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, + 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x16, 0x0a, 0x14, 0x50, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x48, 0x0a, 0x14, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x17, 0x0a, + 0x15, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x93, 0x01, 0x0a, 0x1f, 0x54, 0x72, 0x75, 0x73, 0x74, + 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, + 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, + 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0x89, 0x01, 0x0a, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x4f, 0x0a, 0x07, 0x42, 0x75, 0x6e, 0x64, 0x6c, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, - 0x12, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, - 0x64, 0x6c, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, - 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x53, 0x0a, 0x1f, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, - 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x22, 0x0a, 0x20, 0x50, - 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, - 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x9a, 0x02, 0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x65, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x41, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x38, 0x0a, 0x17, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x17, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x65, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3b, 0x0a, 0x15, - 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x50, 0x65, 0x65, - 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xfc, 0x01, 0x0a, 0x10, 0x45, 0x73, - 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x50, 0x65, - 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1c, - 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x51, 0x0a, 0x04, - 0x4d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x68, 0x61, 0x73, + 0x07, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x22, 0x4a, 0x0a, 0x16, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7e, 0x0a, 0x17, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x4d, 0x0a, 0x06, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x06, 0x42, 0x75, + 0x6e, 0x64, 0x6c, 0x65, 0x22, 0x2d, 0x0a, 0x1b, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x49, 0x44, 0x22, 0x1e, 0x0a, 0x1c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x65, + 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x1e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x65, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x12, 0x50, 0x65, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x22, 0x21, 0x0a, + 0x1f, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x53, 0x0a, 0x1f, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, + 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x22, 0x0a, 0x20, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, + 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, 0x02, 0x0a, 0x14, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x04, + 0x4d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x45, - 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, - 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x1a, - 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x13, 0x0a, 0x11, 0x45, 0x73, 0x74, 0x61, - 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x73, 0x0a, - 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0d, 0x0a, - 0x09, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, - 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x53, 0x54, - 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x41, - 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x41, 0x49, 0x4c, 0x49, - 0x4e, 0x47, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x49, 0x4e, 0x47, - 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, - 0x10, 0x06, 0x32, 0xc0, 0x08, 0x0a, 0x0e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x09, 0x45, 0x73, - 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x45, 0x73, 0x74, 0x61, - 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, - 0x64, 0x12, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, + 0x65, 0x74, 0x61, 0x12, 0x38, 0x0a, 0x17, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x17, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x1a, 0x37, 0x0a, + 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3b, 0x0a, 0x15, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x22, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0xfc, 0x01, 0x0a, 0x10, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x65, 0x65, 0x72, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x50, 0x65, 0x65, 0x72, + 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, + 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x51, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, + 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, + 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0x13, 0x0a, 0x11, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x73, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x44, 0x45, 0x46, + 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, + 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, + 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, + 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x41, 0x49, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x0c, + 0x0a, 0x08, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, + 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, 0x10, 0x06, 0x32, 0xc0, 0x08, 0x0a, + 0x0e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x82, 0x01, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, - 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, - 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x7c, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, - 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, - 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x09, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x12, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, - 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, - 0x01, 0x0a, 0x0d, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x12, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, - 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, - 0x69, 0x74, 0x65, 0x12, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, - 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, - 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x68, 0x61, + 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x45, 0x73, 0x74, 0x61, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x0b, + 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x12, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xa3, 0x01, 0x0a, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, - 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, - 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, - 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x43, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x0f, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x12, 0x39, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, - 0x6e, 0x67, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, - 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x0b, 0x50, 0x65, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x72, - 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x8a, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x0d, 0x50, 0x65, 0x65, + 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x37, 0x2e, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, + 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, + 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x36, 0x2e, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xa3, + 0x01, 0x0a, 0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x42, - 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0xa2, 0x02, 0x04, 0x48, - 0x43, 0x49, 0x50, 0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, - 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0xca, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x5c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0xe2, 0x02, 0x2d, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, - 0x3a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3a, 0x3a, 0x50, 0x65, 0x65, 0x72, 0x69, - 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, + 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x43, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, + 0x69, 0x73, 0x74, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x0f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, + 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x12, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, + 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, + 0x8a, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x70, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0xa2, 0x02, 0x04, 0x48, 0x43, 0x49, 0x50, 0xaa, 0x02, 0x21, + 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0xca, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x50, 0x65, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x5c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x3a, 0x3a, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2186,84 +2434,89 @@ func file_proto_pbpeering_peering_proto_rawDescGZIP() []byte { return file_proto_pbpeering_peering_proto_rawDescData } -var file_proto_pbpeering_peering_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_proto_pbpeering_peering_proto_msgTypes = make([]protoimpl.MessageInfo, 32) +var file_proto_pbpeering_peering_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_proto_pbpeering_peering_proto_msgTypes = make([]protoimpl.MessageInfo, 36) var file_proto_pbpeering_peering_proto_goTypes = []interface{}{ - (PeeringState)(0), // 0: hashicorp.consul.internal.peering.PeeringState - (PeeringSecretsWriteRequest_Operation)(0), // 1: hashicorp.consul.internal.peering.PeeringSecretsWriteRequest.Operation - (*PeeringSecretsWriteRequest)(nil), // 2: hashicorp.consul.internal.peering.PeeringSecretsWriteRequest - (*PeeringSecrets)(nil), // 3: hashicorp.consul.internal.peering.PeeringSecrets - (*Peering)(nil), // 4: hashicorp.consul.internal.peering.Peering - (*PeeringTrustBundle)(nil), // 5: hashicorp.consul.internal.peering.PeeringTrustBundle - (*PeeringReadRequest)(nil), // 6: hashicorp.consul.internal.peering.PeeringReadRequest - (*PeeringReadResponse)(nil), // 7: hashicorp.consul.internal.peering.PeeringReadResponse - (*PeeringListRequest)(nil), // 8: hashicorp.consul.internal.peering.PeeringListRequest - (*PeeringListResponse)(nil), // 9: hashicorp.consul.internal.peering.PeeringListResponse - (*PeeringWriteRequest)(nil), // 10: hashicorp.consul.internal.peering.PeeringWriteRequest - (*PeeringWriteResponse)(nil), // 11: hashicorp.consul.internal.peering.PeeringWriteResponse - (*PeeringDeleteRequest)(nil), // 12: hashicorp.consul.internal.peering.PeeringDeleteRequest - (*PeeringDeleteResponse)(nil), // 13: hashicorp.consul.internal.peering.PeeringDeleteResponse - (*TrustBundleListByServiceRequest)(nil), // 14: hashicorp.consul.internal.peering.TrustBundleListByServiceRequest - (*TrustBundleListByServiceResponse)(nil), // 15: hashicorp.consul.internal.peering.TrustBundleListByServiceResponse - (*TrustBundleReadRequest)(nil), // 16: hashicorp.consul.internal.peering.TrustBundleReadRequest - (*TrustBundleReadResponse)(nil), // 17: hashicorp.consul.internal.peering.TrustBundleReadResponse - (*PeeringTerminateByIDRequest)(nil), // 18: hashicorp.consul.internal.peering.PeeringTerminateByIDRequest - (*PeeringTerminateByIDResponse)(nil), // 19: hashicorp.consul.internal.peering.PeeringTerminateByIDResponse - (*PeeringTrustBundleWriteRequest)(nil), // 20: hashicorp.consul.internal.peering.PeeringTrustBundleWriteRequest - (*PeeringTrustBundleWriteResponse)(nil), // 21: hashicorp.consul.internal.peering.PeeringTrustBundleWriteResponse - (*PeeringTrustBundleDeleteRequest)(nil), // 22: hashicorp.consul.internal.peering.PeeringTrustBundleDeleteRequest - (*PeeringTrustBundleDeleteResponse)(nil), // 23: hashicorp.consul.internal.peering.PeeringTrustBundleDeleteResponse - (*GenerateTokenRequest)(nil), // 24: hashicorp.consul.internal.peering.GenerateTokenRequest - (*GenerateTokenResponse)(nil), // 25: hashicorp.consul.internal.peering.GenerateTokenResponse - (*EstablishRequest)(nil), // 26: hashicorp.consul.internal.peering.EstablishRequest - (*EstablishResponse)(nil), // 27: hashicorp.consul.internal.peering.EstablishResponse - (*PeeringSecrets_Establishment)(nil), // 28: hashicorp.consul.internal.peering.PeeringSecrets.Establishment - (*PeeringSecrets_Stream)(nil), // 29: hashicorp.consul.internal.peering.PeeringSecrets.Stream - nil, // 30: hashicorp.consul.internal.peering.Peering.MetaEntry - nil, // 31: hashicorp.consul.internal.peering.PeeringWriteRequest.MetaEntry - nil, // 32: hashicorp.consul.internal.peering.GenerateTokenRequest.MetaEntry - nil, // 33: hashicorp.consul.internal.peering.EstablishRequest.MetaEntry - (*timestamppb.Timestamp)(nil), // 34: google.protobuf.Timestamp + (PeeringState)(0), // 0: hashicorp.consul.internal.peering.PeeringState + (*SecretsWriteRequest)(nil), // 1: hashicorp.consul.internal.peering.SecretsWriteRequest + (*PeeringSecrets)(nil), // 2: hashicorp.consul.internal.peering.PeeringSecrets + (*Peering)(nil), // 3: hashicorp.consul.internal.peering.Peering + (*PeeringTrustBundle)(nil), // 4: hashicorp.consul.internal.peering.PeeringTrustBundle + (*PeeringReadRequest)(nil), // 5: hashicorp.consul.internal.peering.PeeringReadRequest + (*PeeringReadResponse)(nil), // 6: hashicorp.consul.internal.peering.PeeringReadResponse + (*PeeringListRequest)(nil), // 7: hashicorp.consul.internal.peering.PeeringListRequest + (*PeeringListResponse)(nil), // 8: hashicorp.consul.internal.peering.PeeringListResponse + (*PeeringWriteRequest)(nil), // 9: hashicorp.consul.internal.peering.PeeringWriteRequest + (*PeeringWriteResponse)(nil), // 10: hashicorp.consul.internal.peering.PeeringWriteResponse + (*PeeringDeleteRequest)(nil), // 11: hashicorp.consul.internal.peering.PeeringDeleteRequest + (*PeeringDeleteResponse)(nil), // 12: hashicorp.consul.internal.peering.PeeringDeleteResponse + (*TrustBundleListByServiceRequest)(nil), // 13: hashicorp.consul.internal.peering.TrustBundleListByServiceRequest + (*TrustBundleListByServiceResponse)(nil), // 14: hashicorp.consul.internal.peering.TrustBundleListByServiceResponse + (*TrustBundleReadRequest)(nil), // 15: hashicorp.consul.internal.peering.TrustBundleReadRequest + (*TrustBundleReadResponse)(nil), // 16: hashicorp.consul.internal.peering.TrustBundleReadResponse + (*PeeringTerminateByIDRequest)(nil), // 17: hashicorp.consul.internal.peering.PeeringTerminateByIDRequest + (*PeeringTerminateByIDResponse)(nil), // 18: hashicorp.consul.internal.peering.PeeringTerminateByIDResponse + (*PeeringTrustBundleWriteRequest)(nil), // 19: hashicorp.consul.internal.peering.PeeringTrustBundleWriteRequest + (*PeeringTrustBundleWriteResponse)(nil), // 20: hashicorp.consul.internal.peering.PeeringTrustBundleWriteResponse + (*PeeringTrustBundleDeleteRequest)(nil), // 21: hashicorp.consul.internal.peering.PeeringTrustBundleDeleteRequest + (*PeeringTrustBundleDeleteResponse)(nil), // 22: hashicorp.consul.internal.peering.PeeringTrustBundleDeleteResponse + (*GenerateTokenRequest)(nil), // 23: hashicorp.consul.internal.peering.GenerateTokenRequest + (*GenerateTokenResponse)(nil), // 24: hashicorp.consul.internal.peering.GenerateTokenResponse + (*EstablishRequest)(nil), // 25: hashicorp.consul.internal.peering.EstablishRequest + (*EstablishResponse)(nil), // 26: hashicorp.consul.internal.peering.EstablishResponse + (*SecretsWriteRequest_GenerateTokenRequest)(nil), // 27: hashicorp.consul.internal.peering.SecretsWriteRequest.GenerateTokenRequest + (*SecretsWriteRequest_ExchangeSecretRequest)(nil), // 28: hashicorp.consul.internal.peering.SecretsWriteRequest.ExchangeSecretRequest + (*SecretsWriteRequest_PromotePendingRequest)(nil), // 29: hashicorp.consul.internal.peering.SecretsWriteRequest.PromotePendingRequest + (*SecretsWriteRequest_EstablishRequest)(nil), // 30: hashicorp.consul.internal.peering.SecretsWriteRequest.EstablishRequest + (*PeeringSecrets_Establishment)(nil), // 31: hashicorp.consul.internal.peering.PeeringSecrets.Establishment + (*PeeringSecrets_Stream)(nil), // 32: hashicorp.consul.internal.peering.PeeringSecrets.Stream + nil, // 33: hashicorp.consul.internal.peering.Peering.MetaEntry + nil, // 34: hashicorp.consul.internal.peering.PeeringWriteRequest.MetaEntry + nil, // 35: hashicorp.consul.internal.peering.GenerateTokenRequest.MetaEntry + nil, // 36: hashicorp.consul.internal.peering.EstablishRequest.MetaEntry + (*timestamppb.Timestamp)(nil), // 37: google.protobuf.Timestamp } var file_proto_pbpeering_peering_proto_depIdxs = []int32{ - 3, // 0: hashicorp.consul.internal.peering.PeeringSecretsWriteRequest.secrets:type_name -> hashicorp.consul.internal.peering.PeeringSecrets - 1, // 1: hashicorp.consul.internal.peering.PeeringSecretsWriteRequest.operation:type_name -> hashicorp.consul.internal.peering.PeeringSecretsWriteRequest.Operation - 28, // 2: hashicorp.consul.internal.peering.PeeringSecrets.establishment:type_name -> hashicorp.consul.internal.peering.PeeringSecrets.Establishment - 29, // 3: hashicorp.consul.internal.peering.PeeringSecrets.stream:type_name -> hashicorp.consul.internal.peering.PeeringSecrets.Stream - 34, // 4: hashicorp.consul.internal.peering.Peering.DeletedAt:type_name -> google.protobuf.Timestamp - 30, // 5: hashicorp.consul.internal.peering.Peering.Meta:type_name -> hashicorp.consul.internal.peering.Peering.MetaEntry - 0, // 6: hashicorp.consul.internal.peering.Peering.State:type_name -> hashicorp.consul.internal.peering.PeeringState - 4, // 7: hashicorp.consul.internal.peering.PeeringReadResponse.Peering:type_name -> hashicorp.consul.internal.peering.Peering - 4, // 8: hashicorp.consul.internal.peering.PeeringListResponse.Peerings:type_name -> hashicorp.consul.internal.peering.Peering - 4, // 9: hashicorp.consul.internal.peering.PeeringWriteRequest.Peering:type_name -> hashicorp.consul.internal.peering.Peering - 2, // 10: hashicorp.consul.internal.peering.PeeringWriteRequest.SecretsRequest:type_name -> hashicorp.consul.internal.peering.PeeringSecretsWriteRequest - 31, // 11: hashicorp.consul.internal.peering.PeeringWriteRequest.Meta:type_name -> hashicorp.consul.internal.peering.PeeringWriteRequest.MetaEntry - 5, // 12: hashicorp.consul.internal.peering.TrustBundleListByServiceResponse.Bundles:type_name -> hashicorp.consul.internal.peering.PeeringTrustBundle - 5, // 13: hashicorp.consul.internal.peering.TrustBundleReadResponse.Bundle:type_name -> hashicorp.consul.internal.peering.PeeringTrustBundle - 5, // 14: hashicorp.consul.internal.peering.PeeringTrustBundleWriteRequest.PeeringTrustBundle:type_name -> hashicorp.consul.internal.peering.PeeringTrustBundle - 32, // 15: hashicorp.consul.internal.peering.GenerateTokenRequest.Meta:type_name -> hashicorp.consul.internal.peering.GenerateTokenRequest.MetaEntry - 33, // 16: hashicorp.consul.internal.peering.EstablishRequest.Meta:type_name -> hashicorp.consul.internal.peering.EstablishRequest.MetaEntry - 24, // 17: hashicorp.consul.internal.peering.PeeringService.GenerateToken:input_type -> hashicorp.consul.internal.peering.GenerateTokenRequest - 26, // 18: hashicorp.consul.internal.peering.PeeringService.Establish:input_type -> hashicorp.consul.internal.peering.EstablishRequest - 6, // 19: hashicorp.consul.internal.peering.PeeringService.PeeringRead:input_type -> hashicorp.consul.internal.peering.PeeringReadRequest - 8, // 20: hashicorp.consul.internal.peering.PeeringService.PeeringList:input_type -> hashicorp.consul.internal.peering.PeeringListRequest - 12, // 21: hashicorp.consul.internal.peering.PeeringService.PeeringDelete:input_type -> hashicorp.consul.internal.peering.PeeringDeleteRequest - 10, // 22: hashicorp.consul.internal.peering.PeeringService.PeeringWrite:input_type -> hashicorp.consul.internal.peering.PeeringWriteRequest - 14, // 23: hashicorp.consul.internal.peering.PeeringService.TrustBundleListByService:input_type -> hashicorp.consul.internal.peering.TrustBundleListByServiceRequest - 16, // 24: hashicorp.consul.internal.peering.PeeringService.TrustBundleRead:input_type -> hashicorp.consul.internal.peering.TrustBundleReadRequest - 25, // 25: hashicorp.consul.internal.peering.PeeringService.GenerateToken:output_type -> hashicorp.consul.internal.peering.GenerateTokenResponse - 27, // 26: hashicorp.consul.internal.peering.PeeringService.Establish:output_type -> hashicorp.consul.internal.peering.EstablishResponse - 7, // 27: hashicorp.consul.internal.peering.PeeringService.PeeringRead:output_type -> hashicorp.consul.internal.peering.PeeringReadResponse - 9, // 28: hashicorp.consul.internal.peering.PeeringService.PeeringList:output_type -> hashicorp.consul.internal.peering.PeeringListResponse - 13, // 29: hashicorp.consul.internal.peering.PeeringService.PeeringDelete:output_type -> hashicorp.consul.internal.peering.PeeringDeleteResponse - 11, // 30: hashicorp.consul.internal.peering.PeeringService.PeeringWrite:output_type -> hashicorp.consul.internal.peering.PeeringWriteResponse - 15, // 31: hashicorp.consul.internal.peering.PeeringService.TrustBundleListByService:output_type -> hashicorp.consul.internal.peering.TrustBundleListByServiceResponse - 17, // 32: hashicorp.consul.internal.peering.PeeringService.TrustBundleRead:output_type -> hashicorp.consul.internal.peering.TrustBundleReadResponse - 25, // [25:33] is the sub-list for method output_type - 17, // [17:25] is the sub-list for method input_type - 17, // [17:17] is the sub-list for extension type_name - 17, // [17:17] is the sub-list for extension extendee - 0, // [0:17] is the sub-list for field type_name + 27, // 0: hashicorp.consul.internal.peering.SecretsWriteRequest.generate_token:type_name -> hashicorp.consul.internal.peering.SecretsWriteRequest.GenerateTokenRequest + 28, // 1: hashicorp.consul.internal.peering.SecretsWriteRequest.exchange_secret:type_name -> hashicorp.consul.internal.peering.SecretsWriteRequest.ExchangeSecretRequest + 29, // 2: hashicorp.consul.internal.peering.SecretsWriteRequest.promote_pending:type_name -> hashicorp.consul.internal.peering.SecretsWriteRequest.PromotePendingRequest + 30, // 3: hashicorp.consul.internal.peering.SecretsWriteRequest.establish:type_name -> hashicorp.consul.internal.peering.SecretsWriteRequest.EstablishRequest + 31, // 4: hashicorp.consul.internal.peering.PeeringSecrets.establishment:type_name -> hashicorp.consul.internal.peering.PeeringSecrets.Establishment + 32, // 5: hashicorp.consul.internal.peering.PeeringSecrets.stream:type_name -> hashicorp.consul.internal.peering.PeeringSecrets.Stream + 37, // 6: hashicorp.consul.internal.peering.Peering.DeletedAt:type_name -> google.protobuf.Timestamp + 33, // 7: hashicorp.consul.internal.peering.Peering.Meta:type_name -> hashicorp.consul.internal.peering.Peering.MetaEntry + 0, // 8: hashicorp.consul.internal.peering.Peering.State:type_name -> hashicorp.consul.internal.peering.PeeringState + 3, // 9: hashicorp.consul.internal.peering.PeeringReadResponse.Peering:type_name -> hashicorp.consul.internal.peering.Peering + 3, // 10: hashicorp.consul.internal.peering.PeeringListResponse.Peerings:type_name -> hashicorp.consul.internal.peering.Peering + 3, // 11: hashicorp.consul.internal.peering.PeeringWriteRequest.Peering:type_name -> hashicorp.consul.internal.peering.Peering + 1, // 12: hashicorp.consul.internal.peering.PeeringWriteRequest.SecretsRequest:type_name -> hashicorp.consul.internal.peering.SecretsWriteRequest + 34, // 13: hashicorp.consul.internal.peering.PeeringWriteRequest.Meta:type_name -> hashicorp.consul.internal.peering.PeeringWriteRequest.MetaEntry + 4, // 14: hashicorp.consul.internal.peering.TrustBundleListByServiceResponse.Bundles:type_name -> hashicorp.consul.internal.peering.PeeringTrustBundle + 4, // 15: hashicorp.consul.internal.peering.TrustBundleReadResponse.Bundle:type_name -> hashicorp.consul.internal.peering.PeeringTrustBundle + 4, // 16: hashicorp.consul.internal.peering.PeeringTrustBundleWriteRequest.PeeringTrustBundle:type_name -> hashicorp.consul.internal.peering.PeeringTrustBundle + 35, // 17: hashicorp.consul.internal.peering.GenerateTokenRequest.Meta:type_name -> hashicorp.consul.internal.peering.GenerateTokenRequest.MetaEntry + 36, // 18: hashicorp.consul.internal.peering.EstablishRequest.Meta:type_name -> hashicorp.consul.internal.peering.EstablishRequest.MetaEntry + 23, // 19: hashicorp.consul.internal.peering.PeeringService.GenerateToken:input_type -> hashicorp.consul.internal.peering.GenerateTokenRequest + 25, // 20: hashicorp.consul.internal.peering.PeeringService.Establish:input_type -> hashicorp.consul.internal.peering.EstablishRequest + 5, // 21: hashicorp.consul.internal.peering.PeeringService.PeeringRead:input_type -> hashicorp.consul.internal.peering.PeeringReadRequest + 7, // 22: hashicorp.consul.internal.peering.PeeringService.PeeringList:input_type -> hashicorp.consul.internal.peering.PeeringListRequest + 11, // 23: hashicorp.consul.internal.peering.PeeringService.PeeringDelete:input_type -> hashicorp.consul.internal.peering.PeeringDeleteRequest + 9, // 24: hashicorp.consul.internal.peering.PeeringService.PeeringWrite:input_type -> hashicorp.consul.internal.peering.PeeringWriteRequest + 13, // 25: hashicorp.consul.internal.peering.PeeringService.TrustBundleListByService:input_type -> hashicorp.consul.internal.peering.TrustBundleListByServiceRequest + 15, // 26: hashicorp.consul.internal.peering.PeeringService.TrustBundleRead:input_type -> hashicorp.consul.internal.peering.TrustBundleReadRequest + 24, // 27: hashicorp.consul.internal.peering.PeeringService.GenerateToken:output_type -> hashicorp.consul.internal.peering.GenerateTokenResponse + 26, // 28: hashicorp.consul.internal.peering.PeeringService.Establish:output_type -> hashicorp.consul.internal.peering.EstablishResponse + 6, // 29: hashicorp.consul.internal.peering.PeeringService.PeeringRead:output_type -> hashicorp.consul.internal.peering.PeeringReadResponse + 8, // 30: hashicorp.consul.internal.peering.PeeringService.PeeringList:output_type -> hashicorp.consul.internal.peering.PeeringListResponse + 12, // 31: hashicorp.consul.internal.peering.PeeringService.PeeringDelete:output_type -> hashicorp.consul.internal.peering.PeeringDeleteResponse + 10, // 32: hashicorp.consul.internal.peering.PeeringService.PeeringWrite:output_type -> hashicorp.consul.internal.peering.PeeringWriteResponse + 14, // 33: hashicorp.consul.internal.peering.PeeringService.TrustBundleListByService:output_type -> hashicorp.consul.internal.peering.TrustBundleListByServiceResponse + 16, // 34: hashicorp.consul.internal.peering.PeeringService.TrustBundleRead:output_type -> hashicorp.consul.internal.peering.TrustBundleReadResponse + 27, // [27:35] is the sub-list for method output_type + 19, // [19:27] is the sub-list for method input_type + 19, // [19:19] is the sub-list for extension type_name + 19, // [19:19] is the sub-list for extension extendee + 0, // [0:19] is the sub-list for field type_name } func init() { file_proto_pbpeering_peering_proto_init() } @@ -2273,7 +2526,7 @@ func file_proto_pbpeering_peering_proto_init() { } if !protoimpl.UnsafeEnabled { file_proto_pbpeering_peering_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeeringSecretsWriteRequest); i { + switch v := v.(*SecretsWriteRequest); i { case 0: return &v.state case 1: @@ -2585,7 +2838,7 @@ func file_proto_pbpeering_peering_proto_init() { } } file_proto_pbpeering_peering_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeeringSecrets_Establishment); i { + switch v := v.(*SecretsWriteRequest_GenerateTokenRequest); i { case 0: return &v.state case 1: @@ -2597,6 +2850,54 @@ func file_proto_pbpeering_peering_proto_init() { } } file_proto_pbpeering_peering_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SecretsWriteRequest_ExchangeSecretRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_pbpeering_peering_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SecretsWriteRequest_PromotePendingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_pbpeering_peering_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SecretsWriteRequest_EstablishRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_pbpeering_peering_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeeringSecrets_Establishment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_pbpeering_peering_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PeeringSecrets_Stream); i { case 0: return &v.state @@ -2609,13 +2910,19 @@ func file_proto_pbpeering_peering_proto_init() { } } } + file_proto_pbpeering_peering_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*SecretsWriteRequest_GenerateToken)(nil), + (*SecretsWriteRequest_ExchangeSecret)(nil), + (*SecretsWriteRequest_PromotePending)(nil), + (*SecretsWriteRequest_Establish)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_pbpeering_peering_proto_rawDesc, - NumEnums: 2, - NumMessages: 32, + NumEnums: 1, + NumMessages: 36, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/pbpeering/peering.proto b/proto/pbpeering/peering.proto index 53de24eadb..b3042d2639 100644 --- a/proto/pbpeering/peering.proto +++ b/proto/pbpeering/peering.proto @@ -53,22 +53,54 @@ enum PeeringState { TERMINATED = 6; } -message PeeringSecretsWriteRequest { - enum Operation { - OPERATION_UNSPECIFIED = 0; +// SecretsWriteRequest encodes a request to write a peering secret as the result +// of some operation. Different operations, such as generating a peering token, +// lead to modifying the known secrets associated with a peering. +message SecretsWriteRequest { + // PeerID is the local UUID of the peering this request applies to. + string PeerID = 1; - OPERATION_GENERATETOKEN = 1; - - OPERATION_EXCHANGESECRET = 2; - - OPERATION_PROMOTEPENDING = 3; + oneof Request { + GenerateTokenRequest generate_token = 2; + ExchangeSecretRequest exchange_secret = 3; + PromotePendingRequest promote_pending = 4; + EstablishRequest establish = 5; } - // Secret contains the peering secrets to write. - PeeringSecrets secrets = 1; + // GenerateTokenRequest encodes a request to persist a peering establishment + // secret. It is triggered by generating a new peering token for a peer cluster. + message GenerateTokenRequest{ + // establishment_secret is the proposed secret ID to store as the establishment + // secret for this peering. + string establishment_secret = 1; + } - // Operation defines which action triggered the secrets write. - Operation operation = 2; + // ExchangeSecretRequest encodes a request to persist a pending stream secret + // secret. It is triggered by an acceptor peer generating a long-lived stream secret + // in exchange for an establishment secret. + message ExchangeSecretRequest { + // pending_stream_secret is the proposed secret ID to store as the pending stream + // secret for this peering. + string pending_stream_secret = 1; + } + + // PromotePendingRequest encodes a request to promote a pending stream secret + // to be an active stream secret. It is triggered when the accepting stream handler + // validates an Open request from a peer with a pending stream secret. + message PromotePendingRequest { + // active_stream_secret is the proposed secret ID to store as the active stream + // secret for this peering. + string active_stream_secret = 1; + } + + // EstablishRequest encodes a request to persist an active stream secret. + // It is triggered after a dialing peer exchanges their establishment secret + // for a long-lived active stream secret. + message EstablishRequest { + // active_stream_secret is the proposed secret ID to store as the active stream + // secret for this peering. + string active_stream_secret = 1; + } } // PeeringSecrets defines a secret used for authenticating/authorizing peer clusters. @@ -213,10 +245,10 @@ message PeeringWriteRequest { // Peering is the peering to write with the request. Peering Peering = 1; - // Secret contains the optional peering secrets to persist + // SecretsWriteRequest contains the optional peering secrets to persist // with the peering. Peering secrets are not embedded in the peering // object to avoid leaking them. - PeeringSecretsWriteRequest SecretsRequest = 2; + SecretsWriteRequest SecretsRequest = 2; map Meta = 3; } diff --git a/sdk/testutil/testlog.go b/sdk/testutil/testlog.go index 9cc99d9700..bb41c4b55a 100644 --- a/sdk/testutil/testlog.go +++ b/sdk/testutil/testlog.go @@ -21,7 +21,7 @@ func testLogLevel() hclog.Level { if level != hclog.NoLevel { return level } - return hclog.Trace + return hclog.Warn } func Logger(t TestingTB) hclog.InterceptLogger {