api: ensure peering API endpoints do not use protobufs (#13204)

I noticed that the JSON api endpoints for peerings json encodes protobufs directly, rather than converting them into their `api` package equivalents before marshal/unmarshaling them.

I updated this and used `mog` to do the annoying part in the middle. 

Other changes:
- the status enum was converted into the friendlier string form of the enum for readability with tools like `curl`
- some of the `api` library functions were slightly modified to match other similar endpoints in UX (cc: @ndhanushkodi )
- peeringRead returns `nil` if not found
- partitions are NOT inferred from the agent's partition (matching 1.11-style logic)
This commit is contained in:
R.B. Boyer 2022-05-25 13:43:35 -05:00 committed by GitHub
parent 72a1aea56c
commit a85b8a4705
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 584 additions and 350 deletions

View File

@ -168,6 +168,14 @@ jobs:
- run: go install github.com/hashicorp/lint-consul-retry@master && lint-consul-retry
- run: *notify-slack-failure
lint-enums:
docker:
- image: *GOLANG_IMAGE
steps:
- checkout
- run: go install github.com/reillywatson/enumcover/cmd/enumcover@master && enumcover ./...
- run: *notify-slack-failure
lint:
description: "Run golangci-lint"
parameters:
@ -1039,6 +1047,7 @@ workflows:
- /^docs\/.*/
- /^ui\/.*/
- check-generated-protobuf: *filter-ignore-non-go-branches
- lint-enums: *filter-ignore-non-go-branches
- lint-consul-retry: *filter-ignore-non-go-branches
- lint: *filter-ignore-non-go-branches
- lint:

View File

@ -272,6 +272,8 @@ lint: lint-tools
(cd sdk && golangci-lint run --build-tags '$(GOTAGS)')
@echo "--> Running lint-consul-retry"
@lint-consul-retry
@echo "--> Running enumcover"
@enumcover ./...
# If you've run "make ui" manually then this will get called for you. This is
# also run as part of the release build script when it verifies that there are no

View File

@ -4,6 +4,8 @@ import (
"fmt"
"net/http"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/proto/pbpeering"
)
@ -18,17 +20,12 @@ func (s *HTTPHandlers) PeeringEndpoint(resp http.ResponseWriter, req *http.Reque
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Must specify a name to fetch."}
}
entMeta := s.agent.AgentEnterpriseMeta()
if err := s.parseEntMetaPartition(req, entMeta); err != nil {
return nil, err
}
// Switch on the method
switch req.Method {
case "GET":
return s.peeringRead(resp, req, name, entMeta.PartitionOrEmpty())
return s.peeringRead(resp, req, name)
case "DELETE":
return s.peeringDelete(resp, req, name, entMeta.PartitionOrEmpty())
return s.peeringDelete(resp, req, name)
default:
return nil, MethodNotAllowedError{req.Method, []string{"GET", "DELETE"}}
}
@ -36,12 +33,16 @@ func (s *HTTPHandlers) PeeringEndpoint(resp http.ResponseWriter, req *http.Reque
// peeringRead fetches a peering that matches the name and partition.
// This assumes that the name and partition parameters are valid
func (s *HTTPHandlers) peeringRead(resp http.ResponseWriter, req *http.Request, name, partition string) (interface{}, error) {
func (s *HTTPHandlers) peeringRead(resp http.ResponseWriter, req *http.Request, name string) (interface{}, error) {
args := pbpeering.PeeringReadRequest{
Name: name,
Datacenter: s.agent.config.Datacenter,
Partition: partition, // should be "" in OSS
}
var entMeta acl.EnterpriseMeta
if err := s.parseEntMetaPartition(req, &entMeta); err != nil {
return nil, err
}
args.Partition = entMeta.PartitionOrEmpty()
result, err := s.agent.rpcClientPeering.PeeringRead(req.Context(), &args)
if err != nil {
@ -51,76 +52,77 @@ func (s *HTTPHandlers) peeringRead(resp http.ResponseWriter, req *http.Request,
return nil, HTTPError{StatusCode: http.StatusNotFound, Reason: fmt.Sprintf("Peering not found for %q", name)}
}
// TODO(peering): replace with API types
return result.Peering, nil
return result.Peering.ToAPI(), nil
}
// PeeringList fetches all peerings in the datacenter in OSS or in a given partition in Consul Enterprise.
func (s *HTTPHandlers) PeeringList(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
entMeta := s.agent.AgentEnterpriseMeta()
if err := s.parseEntMetaPartition(req, entMeta); err != nil {
return nil, err
}
args := pbpeering.PeeringListRequest{
Datacenter: s.agent.config.Datacenter,
Partition: entMeta.PartitionOrEmpty(), // should be "" in OSS
}
var entMeta acl.EnterpriseMeta
if err := s.parseEntMetaPartition(req, &entMeta); err != nil {
return nil, err
}
args.Partition = entMeta.PartitionOrEmpty()
pbresp, err := s.agent.rpcClientPeering.PeeringList(req.Context(), &args)
if err != nil {
return nil, err
}
return pbresp.Peerings, nil
return pbresp.ToAPI(), nil
}
// PeeringGenerateToken handles POSTs to the /v1/peering/token endpoint. The request
// will always be forwarded via RPC to the local leader.
func (s *HTTPHandlers) PeeringGenerateToken(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
// TODO(peering): decode into api type
args := pbpeering.GenerateTokenRequest{
Datacenter: s.agent.config.Datacenter,
}
if req.Body == nil {
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "The peering arguments must be provided in the body"}
}
if err := lib.DecodeJSON(req.Body, &args); err != nil {
apiRequest := &api.PeeringGenerateTokenRequest{
Datacenter: s.agent.config.Datacenter,
}
if err := lib.DecodeJSON(req.Body, apiRequest); err != nil {
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: fmt.Sprintf("Body decoding failed: %v", err)}
}
args := pbpeering.NewGenerateTokenRequestFromAPI(apiRequest)
if args.PeerName == "" {
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "PeerName is required in the payload when generating a new peering token."}
}
entMeta := s.agent.AgentEnterpriseMeta()
if err := s.parseEntMetaPartition(req, entMeta); err != nil {
var entMeta acl.EnterpriseMeta
if err := s.parseEntMetaPartition(req, &entMeta); err != nil {
return nil, err
}
if args.Partition == "" {
args.Partition = entMeta.PartitionOrEmpty()
}
return s.agent.rpcClientPeering.GenerateToken(req.Context(), &args)
out, err := s.agent.rpcClientPeering.GenerateToken(req.Context(), args)
if err != nil {
return nil, err
}
return out.ToAPI(), nil
}
// PeeringInitiate handles POSTs to the /v1/peering/initiate endpoint. The request
// will always be forwarded via RPC to the local leader.
func (s *HTTPHandlers) PeeringInitiate(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
// TODO(peering): decode into api type
args := pbpeering.InitiateRequest{
Datacenter: s.agent.config.Datacenter,
}
if req.Body == nil {
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "The peering arguments must be provided in the body"}
}
if err := lib.DecodeJSON(req.Body, &args); err != nil {
apiRequest := &api.PeeringInitiateRequest{
Datacenter: s.agent.config.Datacenter,
}
if err := lib.DecodeJSON(req.Body, apiRequest); err != nil {
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: fmt.Sprintf("Body decoding failed: %v", err)}
}
args := pbpeering.NewInitiateRequestFromAPI(apiRequest)
if args.PeerName == "" {
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "PeerName is required in the payload when initiating a peering."}
@ -130,23 +132,31 @@ func (s *HTTPHandlers) PeeringInitiate(resp http.ResponseWriter, req *http.Reque
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "PeeringToken is required in the payload when initiating a peering."}
}
return s.agent.rpcClientPeering.Initiate(req.Context(), &args)
}
// peeringDelete initiates a deletion for a peering that matches the name and partition.
// This assumes that the name and partition parameters are valid.
func (s *HTTPHandlers) peeringDelete(resp http.ResponseWriter, req *http.Request, name, partition string) (interface{}, error) {
args := pbpeering.PeeringDeleteRequest{
Name: name,
Datacenter: s.agent.config.Datacenter,
Partition: partition, // should be "" in OSS
}
result, err := s.agent.rpcClientPeering.PeeringDelete(req.Context(), &args)
out, err := s.agent.rpcClientPeering.Initiate(req.Context(), args)
if err != nil {
return nil, err
}
// TODO(peering) -- today pbpeering.PeeringDeleteResponse is a {} so the result below is actually {}
return result, nil
return out.ToAPI(), nil
}
// peeringDelete initiates a deletion for a peering that matches the name and partition.
// This assumes that the name and partition parameters are valid.
func (s *HTTPHandlers) peeringDelete(resp http.ResponseWriter, req *http.Request, name string) (interface{}, error) {
args := pbpeering.PeeringDeleteRequest{
Name: name,
Datacenter: s.agent.config.Datacenter,
}
var entMeta acl.EnterpriseMeta
if err := s.parseEntMetaPartition(req, &entMeta); err != nil {
return nil, err
}
args.Partition = entMeta.PartitionOrEmpty()
_, err := s.agent.rpcClientPeering.PeeringDelete(req.Context(), &args)
if err != nil {
return nil, err
}
return nil, nil
}

View File

@ -15,6 +15,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/proto/pbpeering"
"github.com/hashicorp/consul/testrpc"
)
@ -278,12 +279,11 @@ func TestHTTP_Peering_Read(t *testing.T) {
a.srv.h.ServeHTTP(resp, req)
require.Equal(t, http.StatusOK, resp.Code)
// TODO(peering): replace with API types
var pbresp pbpeering.Peering
require.NoError(t, json.NewDecoder(resp.Body).Decode(&pbresp))
var apiResp api.Peering
require.NoError(t, json.NewDecoder(resp.Body).Decode(&apiResp))
require.Equal(t, foo.Peering.Name, pbresp.Name)
require.Equal(t, foo.Peering.Meta, pbresp.Meta)
require.Equal(t, foo.Peering.Name, apiResp.Name)
require.Equal(t, foo.Peering.Meta, apiResp.Meta)
})
t.Run("not found", func(t *testing.T) {
@ -328,11 +328,10 @@ func TestHTTP_Peering_Delete(t *testing.T) {
a.srv.h.ServeHTTP(resp, req)
require.Equal(t, http.StatusOK, resp.Code)
// TODO(peering): replace with API types
var pbresp pbpeering.Peering
require.NoError(t, json.NewDecoder(resp.Body).Decode(&pbresp))
var apiResp api.Peering
require.NoError(t, json.NewDecoder(resp.Body).Decode(&apiResp))
require.Equal(t, foo.Peering.Name, pbresp.Name)
require.Equal(t, foo.Peering.Name, apiResp.Name)
})
t.Run("delete the existing token we just read", func(t *testing.T) {
@ -341,7 +340,7 @@ func TestHTTP_Peering_Delete(t *testing.T) {
resp := httptest.NewRecorder()
a.srv.h.ServeHTTP(resp, req)
require.Equal(t, http.StatusOK, resp.Code)
require.Equal(t, "{}", resp.Body.String())
require.Equal(t, "", resp.Body.String())
})
t.Run("now the token is deleted, a read should 404", func(t *testing.T) {
@ -408,10 +407,9 @@ func TestHTTP_Peering_List(t *testing.T) {
a.srv.h.ServeHTTP(resp, req)
require.Equal(t, http.StatusOK, resp.Code)
// TODO(peering): replace with API types
var pbresp []*pbpeering.Peering
require.NoError(t, json.NewDecoder(resp.Body).Decode(&pbresp))
var apiResp []*api.Peering
require.NoError(t, json.NewDecoder(resp.Body).Decode(&apiResp))
require.Len(t, pbresp, 2)
require.Len(t, apiResp, 2)
})
}

View File

@ -6,15 +6,27 @@ import (
)
// PeeringState enumerates all the states a peering can be in
type PeeringState int32
type PeeringState string
const (
// PeeringStateUndefined represents an unset value for PeeringState during
// writes.
PeeringStateUndefined PeeringState = 0
PeeringStateUndefined PeeringState = "UNDEFINED"
// PeeringStateInitial means a Peering has been initialized and is awaiting
// acknowledgement from a remote peer.
PeeringStateInitial PeeringState = 1
PeeringStateInitial PeeringState = "INITIAL"
// PeeringStateActive means that the peering connection is active and
// healthy.
PeeringStateActive PeeringState = "ACTIVE"
// PeeringStateFailing means the peering connection has been interrupted
// but has not yet been terminated.
PeeringStateFailing PeeringState = "FAILING"
// PeeringStateTerminated means the peering relationship has been removed.
PeeringStateTerminated PeeringState = "TERMINATED"
)
type Peering struct {
@ -23,53 +35,38 @@ type Peering struct {
// Name is the local alias for the peering relationship.
Name string
// Partition is the local partition connecting to the peer.
Partition string `json:"Partition,omitempty"`
Partition string `json:",omitempty"`
// Meta is a mapping of some string value to any other string value
Meta map[string]string `json:",omitempty"`
// State is one of the valid PeeringState values to represent the status of
// peering relationship.
State PeeringState
// PeerID is the ID that our peer assigned to this peering.
// This ID is to be used when dialing the peer, so that it can know who dialed it.
PeerID string
// PeerID is the ID that our peer assigned to this peering. This ID is to
// be used when dialing the peer, so that it can know who dialed it.
PeerID string `json:",omitempty"`
// PeerCAPems contains all the CA certificates for the remote peer.
PeerCAPems []string
PeerCAPems []string `json:",omitempty"`
// PeerServerName is the name of the remote server as it relates to TLS.
PeerServerName string
PeerServerName string `json:",omitempty"`
// PeerServerAddresses contains all the connection addresses for the remote peer.
PeerServerAddresses []string
PeerServerAddresses []string `json:",omitempty"`
// CreateIndex is the Raft index at which the Peering was created.
CreateIndex uint64
// ModifyIndex is the latest Raft index at which the Peering. was modified.
ModifyIndex uint64
}
type PeeringReadRequest struct {
Name string
Partition string `json:"Partition,omitempty"`
Datacenter string
}
type PeeringDeleteRequest struct {
Name string
Partition string `json:"Partition,omitempty"`
Datacenter string
}
type PeeringReadResponse struct {
Peering *Peering
}
type PeeringDeleteResponse struct {
}
type PeeringGenerateTokenRequest struct {
// PeerName is the name of the remote peer.
PeerName string
// Partition to be peered.
Partition string `json:"Partition,omitempty"`
Datacenter string
Token string
Partition string `json:",omitempty"`
Datacenter string `json:",omitempty"`
Token string `json:",omitempty"`
// Meta is a mapping of some string value to any other string value
Meta map[string]string `json:",omitempty"`
}
@ -84,15 +81,14 @@ type PeeringInitiateRequest struct {
// Name of the remote peer.
PeerName string
// The peering token returned from the peer's GenerateToken endpoint.
PeeringToken string
Datacenter string
Token string
PeeringToken string `json:",omitempty"`
Datacenter string `json:",omitempty"`
Token string `json:",omitempty"`
// Meta is a mapping of some string value to any other string value
Meta map[string]string `json:",omitempty"`
}
type PeeringInitiateResponse struct {
Status uint32
}
type PeeringListRequest struct {
@ -108,22 +104,22 @@ func (c *Client) Peerings() *Peerings {
return &Peerings{c: c}
}
func (p *Peerings) Read(ctx context.Context, peeringReq PeeringReadRequest, q *QueryOptions) (*Peering, *QueryMeta, error) {
if peeringReq.Name == "" {
func (p *Peerings) Read(ctx context.Context, name string, q *QueryOptions) (*Peering, *QueryMeta, error) {
if name == "" {
return nil, nil, fmt.Errorf("peering name cannot be empty")
}
req := p.c.newRequest("GET", fmt.Sprintf("/v1/peering/%s", peeringReq.Name))
req := p.c.newRequest("GET", fmt.Sprintf("/v1/peering/%s", name))
req.setQueryOptions(q)
req.ctx = ctx
req.obj = peeringReq
rtt, resp, err := p.c.doRequest(req)
if err != nil {
return nil, nil, err
}
defer closeResponseBody(resp)
if err := requireOK(resp); err != nil {
found, resp, err := requireNotFoundOrOK(resp)
if err != nil {
return nil, nil, err
}
@ -131,6 +127,10 @@ func (p *Peerings) Read(ctx context.Context, peeringReq PeeringReadRequest, q *Q
parseQueryMeta(resp, qm)
qm.RequestTime = rtt
if !found {
return nil, qm, nil
}
var out Peering
if err := decodeBody(resp, &out); err != nil {
return nil, nil, err
@ -139,37 +139,29 @@ func (p *Peerings) Read(ctx context.Context, peeringReq PeeringReadRequest, q *Q
return &out, qm, nil
}
func (p *Peerings) Delete(ctx context.Context, peeringReq PeeringDeleteRequest, q *QueryOptions) (*PeeringDeleteResponse, *QueryMeta, error) {
if peeringReq.Name == "" {
return nil, nil, fmt.Errorf("peering name cannot be empty")
func (p *Peerings) Delete(ctx context.Context, name string, q *WriteOptions) (*WriteMeta, error) {
if name == "" {
return nil, fmt.Errorf("peering name cannot be empty")
}
req := p.c.newRequest("DELETE", fmt.Sprintf("/v1/peering/%s", peeringReq.Name))
req.setQueryOptions(q)
req.obj = peeringReq
req := p.c.newRequest("DELETE", fmt.Sprintf("/v1/peering/%s", name))
req.setWriteOptions(q)
req.ctx = ctx
rtt, resp, err := p.c.doRequest(req)
if err != nil {
return nil, nil, err
return nil, err
}
defer closeResponseBody(resp)
if err := requireOK(resp); err != nil {
return nil, nil, err
return nil, err
}
qm := &QueryMeta{}
parseQueryMeta(resp, qm)
qm.RequestTime = rtt
var out PeeringDeleteResponse
if err := decodeBody(resp, &out); err != nil {
return nil, nil, err
}
return &out, qm, nil
wm := &WriteMeta{RequestTime: rtt}
return wm, nil
}
// TODO(peering): verify this is the ultimate signature we want
func (p *Peerings) GenerateToken(ctx context.Context, g PeeringGenerateTokenRequest, wq *WriteOptions) (*PeeringGenerateTokenResponse, *WriteMeta, error) {
if g.PeerName == "" {
return nil, nil, fmt.Errorf("peer name cannot be empty")
@ -199,8 +191,8 @@ func (p *Peerings) GenerateToken(ctx context.Context, g PeeringGenerateTokenRequ
return &out, wm, nil
}
// TODO(peering): verify this is the ultimate signature we want
func (p *Peerings) Initiate(ctx context.Context, i PeeringInitiateRequest, wq *WriteOptions) (*PeeringInitiateResponse, *WriteMeta, error) {
req := p.c.newRequest("POST", fmt.Sprint("/v1/peering/initiate"))
req.setWriteOptions(wq)
req.ctx = ctx
@ -225,12 +217,10 @@ func (p *Peerings) Initiate(ctx context.Context, i PeeringInitiateRequest, wq *W
return &out, wm, nil
}
func (p *Peerings) List(ctx context.Context, plr PeeringListRequest, q *QueryOptions) ([]*Peering, *QueryMeta, error) {
func (p *Peerings) List(ctx context.Context, q *QueryOptions) ([]*Peering, *QueryMeta, error) {
req := p.c.newRequest("GET", "/v1/peerings")
req.setQueryOptions(q)
req.ctx = ctx
req.obj = plr
rtt, resp, err := p.c.doRequest(req)
if err != nil {

View File

@ -36,97 +36,98 @@ func peerExistsInPeerListings(peer *Peering, peerings []*Peering) bool {
func TestAPI_Peering_Read_ErrorHandling(t *testing.T) {
t.Parallel()
c, s := makeClientWithCA(t)
defer s.Stop()
s.WaitForSerfCheck(t)
ctx, cancel := context.WithTimeout(context.Background(), DefaultCtxDuration)
defer cancel()
peerings := c.Peerings()
t.Run("call Read with no name", func(t *testing.T) {
resp, qm, err := peerings.Read(ctx, PeeringReadRequest{}, nil)
// basic checks
_, _, err := peerings.Read(ctx, "", nil)
require.EqualError(t, err, "peering name cannot be empty")
require.Empty(t, qm)
require.Empty(t, resp)
})
t.Run("read peer that does not exist on server", func(t *testing.T) {
resp, qm, err := peerings.Read(ctx, PeeringReadRequest{Name: "peer1"}, nil)
// basic checks
require.NotNil(t, err) // 404
require.Empty(t, qm)
require.Empty(t, resp)
resp, qm, err := peerings.Read(ctx, "peer1", nil)
require.NoError(t, err)
require.NotNil(t, qm)
require.Nil(t, resp)
})
}
// TestAPI_Peering_List
func TestAPI_Peering_List(t *testing.T) {
t.Parallel()
c, s := makeClientWithCA(t)
defer s.Stop()
s.WaitForSerfCheck(t)
ctx, cancel := context.WithTimeout(context.Background(), DefaultCtxDuration)
defer cancel()
peerings := c.Peerings()
// "call List when no peers should exist"
resp, qm, err := peerings.List(ctx, PeeringListRequest{}, nil)
testutil.RunStep(t, "list with no peers", func(t *testing.T) {
// "call List when no peers should exist"
resp, qm, err := peerings.List(ctx, nil)
require.NoError(t, err)
require.NotNil(t, qm)
require.Empty(t, resp) // no peerings so this should be empty
})
// basic checks
require.NoError(t, err)
require.NotEmpty(t, qm)
testutil.RunStep(t, "list with some peers", func(t *testing.T) {
// "call List when peers are present"
resp1, wm, err := peerings.GenerateToken(ctx, PeeringGenerateTokenRequest{PeerName: "peer1"}, nil)
require.NoError(t, err)
require.NotNil(t, wm)
require.NotNil(t, resp1)
require.Empty(t, resp) // no peerings so this should be empty
resp2, wm, err := peerings.GenerateToken(ctx, PeeringGenerateTokenRequest{PeerName: "peer2"}, nil)
require.NoError(t, err)
require.NotNil(t, wm)
require.NotNil(t, resp2)
// "call List when peers are present"
resp2, wm, err := peerings.GenerateToken(ctx, PeeringGenerateTokenRequest{PeerName: "peer1"}, nil)
require.NoError(t, err)
require.NotEmpty(t, wm)
require.NotEmpty(t, resp2)
peering1, qm, err := peerings.Read(ctx, "peer1", nil)
require.NoError(t, err)
require.NotNil(t, qm)
require.NotNil(t, peering1)
resp3, wm, err := peerings.GenerateToken(ctx, PeeringGenerateTokenRequest{PeerName: "peer2"}, nil)
require.NoError(t, err)
require.NotEmpty(t, wm)
require.NotEmpty(t, resp3)
peering2, qm, err := peerings.Read(ctx, "peer2", nil)
require.NoError(t, err)
require.NotNil(t, qm)
require.NotNil(t, peering2)
peering1, qm, err2 := peerings.Read(ctx, PeeringReadRequest{Name: "peer1"}, nil)
require.NoError(t, err2)
require.NotEmpty(t, qm)
require.NotEmpty(t, peering1)
peering2, qm, err2 := peerings.Read(ctx, PeeringReadRequest{Name: "peer2"}, nil)
require.NoError(t, err2)
require.NotEmpty(t, qm)
require.NotEmpty(t, peering2)
peeringsList, qm, err := peerings.List(ctx, PeeringListRequest{}, nil)
require.NoError(t, err)
require.NotEmpty(t, qm)
require.Equal(t, 2, len(peeringsList))
require.True(t, peerExistsInPeerListings(peering1, peeringsList), "expected to find peering in list response")
require.True(t, peerExistsInPeerListings(peering2, peeringsList), "expected to find peering in list response")
peeringsList, qm, err := peerings.List(ctx, nil)
require.NoError(t, err)
require.NotNil(t, qm)
require.Len(t, peeringsList, 2)
require.True(t, peerExistsInPeerListings(peering1, peeringsList), "expected to find peering in list response")
require.True(t, peerExistsInPeerListings(peering2, peeringsList), "expected to find peering in list response")
})
}
func TestAPI_Peering_GenerateToken(t *testing.T) {
t.Parallel()
c, s := makeClientWithCA(t)
defer s.Stop()
s.WaitForSerfCheck(t)
ctx, cancel := context.WithTimeout(context.Background(), DefaultCtxDuration)
defer cancel()
peerings := c.Peerings()
t.Run("cannot have GenerateToken forward DC requests", func(t *testing.T) {
// Try to generate a token in dc2
resp, wm, err := peerings.GenerateToken(ctx, PeeringGenerateTokenRequest{PeerName: "peer2", Datacenter: "dc2"}, nil)
_, _, err := peerings.GenerateToken(ctx, PeeringGenerateTokenRequest{PeerName: "peer2", Datacenter: "dc2"}, nil)
require.Error(t, err)
require.Empty(t, wm)
require.Empty(t, resp)
})
}
@ -138,42 +139,41 @@ func TestAPI_Peering_GenerateToken(t *testing.T) {
// finally, we delete the token on the first server
func TestAPI_Peering_GenerateToken_Read_Initiate_Delete(t *testing.T) {
t.Parallel()
c, s := makeClientWithCA(t)
defer s.Stop()
s.WaitForSerfCheck(t)
options := &WriteOptions{Datacenter: "dc1"}
ctx, cancel := context.WithTimeout(context.Background(), DefaultCtxDuration)
defer cancel()
peerings := c.Peerings()
p1 := PeeringGenerateTokenRequest{
PeerName: "peer1",
Meta: map[string]string{"foo": "bar"},
}
var token1 string
// Generate a token happy path
resp, wm, err := peerings.GenerateToken(ctx, p1, options)
testutil.RunStep(t, "generate token", func(t *testing.T) {
// Generate a token happy path
p1 := PeeringGenerateTokenRequest{
PeerName: "peer1",
Meta: map[string]string{"foo": "bar"},
}
resp, wm, err := c.Peerings().GenerateToken(ctx, p1, nil)
require.NoError(t, err)
require.NotNil(t, wm)
require.NotNil(t, resp)
require.NoError(t, err)
require.NotEmpty(t, wm)
require.NotEmpty(t, resp)
token1 = resp.PeeringToken
})
token1 = resp.PeeringToken
testutil.RunStep(t, "verify token", func(t *testing.T) {
// Read token generated on server
resp, qm, err := c.Peerings().Read(ctx, "peer1", nil)
require.NoError(t, err)
require.NotNil(t, qm)
require.NotNil(t, resp)
// Read token generated on server
resp2, qm, err2 := peerings.Read(ctx, PeeringReadRequest{Name: "peer1"}, nil)
// basic ok checking
require.NoError(t, err2)
require.NotEmpty(t, qm)
require.NotEmpty(t, resp2)
// token specific assertions on the "server"
require.Equal(t, "peer1", resp2.Name)
require.Equal(t, PeeringStateInitial, resp2.State)
require.Equal(t, map[string]string{"foo": "bar"}, resp2.Meta)
// Initiate peering
// token specific assertions on the "server"
require.Equal(t, "peer1", resp.Name)
require.Equal(t, PeeringStateInitial, resp.State)
require.Equal(t, map[string]string{"foo": "bar"}, resp.Meta)
})
// make a "client" server in second DC for peering
c2, s2 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) {
@ -181,53 +181,41 @@ func TestAPI_Peering_GenerateToken_Read_Initiate_Delete(t *testing.T) {
})
defer s2.Stop()
i := PeeringInitiateRequest{
Datacenter: c2.config.Datacenter,
PeerName: "peer1",
PeeringToken: token1,
Meta: map[string]string{"foo": "bar"},
}
testutil.RunStep(t, "initiate peering", func(t *testing.T) {
i := PeeringInitiateRequest{
Datacenter: c2.config.Datacenter,
PeerName: "peer1",
PeeringToken: token1,
Meta: map[string]string{"foo": "bar"},
}
respi, wm3, err3 := c2.Peerings().Initiate(ctx, i, options)
_, wm, err := c2.Peerings().Initiate(ctx, i, nil)
require.NoError(t, err)
require.NotNil(t, wm)
// basic checks
require.NoError(t, err3)
require.NotEmpty(t, wm3)
retry.Run(t, func(r *retry.R) {
resp, qm, err := c2.Peerings().Read(ctx, "peer1", nil)
require.NoError(r, err)
require.NotNil(r, qm)
// at first the token will be undefined
require.Equal(t, PeeringStateUndefined, PeeringState(respi.Status))
// require that the peering state is not undefined
require.Equal(r, PeeringStateInitial, resp.State)
require.Equal(r, map[string]string{"foo": "bar"}, resp.Meta)
// wait for the peering backend to finish the peering connection
time.Sleep(2 * time.Second)
retry.Run(t, func(r *retry.R) {
respr, qm2, err4 := c2.Peerings().Read(ctx, PeeringReadRequest{Name: "peer1"}, nil)
// basic ok checking
require.NoError(r, err4)
require.NotEmpty(r, qm2)
// require that the peering state is not undefined
require.Equal(r, PeeringStateInitial, respr.State)
require.Equal(r, map[string]string{"foo": "bar"}, respr.Meta)
// TODO(peering) -- let's go all the way and test in code either here or somewhere else that PeeringState does move to Active
// TODO(peering) -- let's go all the way and test in code either here or somewhere else that PeeringState does move to Active
})
})
// Delete the token on server 1
resp4, qm3, err5 := peerings.Delete(ctx, PeeringDeleteRequest{Name: "peer1"}, nil)
testutil.RunStep(t, "delete peering at source", func(t *testing.T) {
// Delete the token on server 1
wm, err := c.Peerings().Delete(ctx, "peer1", nil)
require.NoError(t, err)
require.NotNil(t, wm)
require.NoError(t, err5)
require.NotEmpty(t, qm3)
// {} is returned on success for now
require.Empty(t, resp4)
// Read to see if the token is "gone"
resp5, qm4, err6 := peerings.Read(ctx, PeeringReadRequest{Name: "peer1"}, nil)
// basic checks
require.NotNil(t, err6)
require.Empty(t, qm4)
require.Empty(t, resp5)
// Read to see if the token is "gone"
resp, qm, err := c.Peerings().Read(ctx, "peer1", nil)
require.NoError(t, err)
require.NotNil(t, qm)
require.Nil(t, resp)
})
}

View File

@ -121,6 +121,10 @@ function lint_install {
'lint-consul-retry' \
'github.com/hashicorp/lint-consul-retry@master'
install_unversioned_tool \
'enumcover' \
'github.com/reillywatson/enumcover/cmd/enumcover@master'
install_versioned_tool \
'golangci-lint' \
'github.com/golangci/golangci-lint' \

View File

@ -0,0 +1,100 @@
// Code generated by mog. DO NOT EDIT.
package pbpeering
import "github.com/hashicorp/consul/api"
func GenerateTokenRequestToAPI(s *GenerateTokenRequest, t *api.PeeringGenerateTokenRequest) {
if s == nil {
return
}
t.PeerName = s.PeerName
t.Partition = s.Partition
t.Datacenter = s.Datacenter
t.Token = s.Token
t.Meta = s.Meta
}
func GenerateTokenRequestFromAPI(t *api.PeeringGenerateTokenRequest, s *GenerateTokenRequest) {
if s == nil {
return
}
s.PeerName = t.PeerName
s.Partition = t.Partition
s.Datacenter = t.Datacenter
s.Token = t.Token
s.Meta = t.Meta
}
func GenerateTokenResponseToAPI(s *GenerateTokenResponse, t *api.PeeringGenerateTokenResponse) {
if s == nil {
return
}
t.PeeringToken = s.PeeringToken
}
func GenerateTokenResponseFromAPI(t *api.PeeringGenerateTokenResponse, s *GenerateTokenResponse) {
if s == nil {
return
}
s.PeeringToken = t.PeeringToken
}
func InitiateRequestToAPI(s *InitiateRequest, t *api.PeeringInitiateRequest) {
if s == nil {
return
}
t.PeerName = s.PeerName
t.PeeringToken = s.PeeringToken
t.Datacenter = s.Datacenter
t.Token = s.Token
t.Meta = s.Meta
}
func InitiateRequestFromAPI(t *api.PeeringInitiateRequest, s *InitiateRequest) {
if s == nil {
return
}
s.PeerName = t.PeerName
s.PeeringToken = t.PeeringToken
s.Datacenter = t.Datacenter
s.Token = t.Token
s.Meta = t.Meta
}
func InitiateResponseToAPI(s *InitiateResponse, t *api.PeeringInitiateResponse) {
if s == nil {
return
}
}
func InitiateResponseFromAPI(t *api.PeeringInitiateResponse, s *InitiateResponse) {
if s == nil {
return
}
}
func PeeringToAPI(s *Peering, t *api.Peering) {
if s == nil {
return
}
t.ID = s.ID
t.Name = s.Name
t.Partition = s.Partition
t.Meta = s.Meta
t.State = PeeringStateToAPI(s.State)
t.PeerID = s.PeerID
t.PeerCAPems = s.PeerCAPems
t.PeerServerName = s.PeerServerName
t.PeerServerAddresses = s.PeerServerAddresses
t.CreateIndex = s.CreateIndex
t.ModifyIndex = s.ModifyIndex
}
func PeeringFromAPI(t *api.Peering, s *Peering) {
if s == nil {
return
}
s.ID = t.ID
s.Name = t.Name
s.Partition = t.Partition
s.Meta = t.Meta
s.State = PeeringStateFromAPI(t.State)
s.PeerID = t.PeerID
s.PeerCAPems = t.PeerCAPems
s.PeerServerName = t.PeerServerName
s.PeerServerAddresses = t.PeerServerAddresses
s.CreateIndex = t.CreateIndex
s.ModifyIndex = t.ModifyIndex
}

View File

@ -1,6 +1,10 @@
package pbpeering
import "time"
import (
"time"
"github.com/hashicorp/consul/api"
)
// TODO(peering): These are byproducts of not embedding
// types in our protobuf definitions and are temporary;
@ -83,3 +87,88 @@ func (p *Peering) ShouldDial() bool {
func (x ReplicationMessage_Response_Operation) GoString() string {
return x.String()
}
// enumcover:PeeringState
func PeeringStateToAPI(s PeeringState) api.PeeringState {
switch s {
case PeeringState_INITIAL:
return api.PeeringStateInitial
case PeeringState_ACTIVE:
return api.PeeringStateActive
case PeeringState_FAILING:
return api.PeeringStateFailing
case PeeringState_TERMINATED:
return api.PeeringStateTerminated
case PeeringState_UNDEFINED:
fallthrough
default:
return api.PeeringStateUndefined
}
}
// enumcover:api.PeeringState
func PeeringStateFromAPI(t api.PeeringState) PeeringState {
switch t {
case api.PeeringStateInitial:
return PeeringState_INITIAL
case api.PeeringStateActive:
return PeeringState_ACTIVE
case api.PeeringStateFailing:
return PeeringState_FAILING
case api.PeeringStateTerminated:
return PeeringState_TERMINATED
case api.PeeringStateUndefined:
fallthrough
default:
return PeeringState_UNDEFINED
}
}
func (p *Peering) ToAPI() *api.Peering {
var t api.Peering
PeeringToAPI(p, &t)
return &t
}
// TODO consider using mog for this
func (resp *PeeringListResponse) ToAPI() []*api.Peering {
list := make([]*api.Peering, len(resp.Peerings))
for i, p := range resp.Peerings {
list[i] = p.ToAPI()
}
return list
}
// TODO consider using mog for this
func (resp *GenerateTokenResponse) ToAPI() *api.PeeringGenerateTokenResponse {
var t api.PeeringGenerateTokenResponse
GenerateTokenResponseToAPI(resp, &t)
return &t
}
// TODO consider using mog for this
func (resp *InitiateResponse) ToAPI() *api.PeeringInitiateResponse {
var t api.PeeringInitiateResponse
InitiateResponseToAPI(resp, &t)
return &t
}
// convenience
func NewGenerateTokenRequestFromAPI(req *api.PeeringGenerateTokenRequest) *GenerateTokenRequest {
if req == nil {
return nil
}
t := &GenerateTokenRequest{}
GenerateTokenRequestFromAPI(req, t)
return t
}
// convenience
func NewInitiateRequestFromAPI(req *api.PeeringInitiateRequest) *InitiateRequest {
if req == nil {
return nil
}
t := &InitiateRequest{}
InitiateRequestFromAPI(req, t)
return t
}

View File

@ -141,6 +141,12 @@ func (ReplicationMessage_Response_Operation) EnumDescriptor() ([]byte, []int) {
}
// Peering defines a peering relationship between two disparate Consul clusters
//
// mog annotation:
//
// target=github.com/hashicorp/consul/api.Peering
// output=peering.gen.go
// name=API
type Peering struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -157,6 +163,8 @@ type Peering struct {
Meta map[string]string `protobuf:"bytes,11,rep,name=Meta,proto3" json:"Meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// State is one of the valid PeeringState values to represent the status of
// peering relationship.
//
// mog: func-to=PeeringStateToAPI func-from=PeeringStateFromAPI
State PeeringState `protobuf:"varint,4,opt,name=State,proto3,enum=peering.PeeringState" json:"State,omitempty"`
// PeerID is the ID that our peer assigned to this peering.
// This ID is to be used when dialing the peer, so that it can know who dialed it.
@ -1194,6 +1202,11 @@ func (*PeeringTrustBundleDeleteResponse) Descriptor() ([]byte, []int) {
return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{17}
}
// mog annotation:
//
// target=github.com/hashicorp/consul/api.PeeringGenerateTokenRequest
// output=peering.gen.go
// name=API
type GenerateTokenRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -1278,6 +1291,11 @@ func (x *GenerateTokenRequest) GetMeta() map[string]string {
return nil
}
// mog annotation:
//
// target=github.com/hashicorp/consul/api.PeeringGenerateTokenResponse
// output=peering.gen.go
// name=API
type GenerateTokenResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -1328,6 +1346,12 @@ func (x *GenerateTokenResponse) GetPeeringToken() string {
}
// @consul-rpc-glue: Datacenter
//
// mog annotation:
//
// target=github.com/hashicorp/consul/api.PeeringInitiateRequest
// output=peering.gen.go
// name=API
type InitiateRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -1421,14 +1445,16 @@ func (x *InitiateRequest) GetMeta() map[string]string {
return nil
}
//
// mog annotation:
//
// target=github.com/hashicorp/consul/api.PeeringInitiateResponse
// output=peering.gen.go
// name=API
type InitiateResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// this is just a placeholder to avoid returning google.protobuf.Empty
// (and consequently gogo.protobuf.types that it will be replaced with)
Status uint32 `protobuf:"varint,1,opt,name=Status,proto3" json:"Status,omitempty"`
}
func (x *InitiateResponse) Reset() {
@ -1463,13 +1489,6 @@ func (*InitiateResponse) Descriptor() ([]byte, []int) {
return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{21}
}
func (x *InitiateResponse) GetStatus() uint32 {
if x != nil {
return x.Status
}
return 0
}
type ReplicationMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -1940,107 +1959,105 @@ var file_proto_pbpeering_peering_proto_rawDesc = []byte{
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, 0x2a, 0x0a, 0x10, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x22, 0x94, 0x05, 0x0a, 0x12, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3f, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69,
0x3a, 0x02, 0x38, 0x01, 0x22, 0x12, 0x0a, 0x10, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x94, 0x05, 0x0a, 0x12, 0x52, 0x65, 0x70,
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
0x3f, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x23, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69,
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x42, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x52, 0x65, 0x70,
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74,
0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69,
0x6e, 0x67, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52,
0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x65, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64,
0x48, 0x00, 0x52, 0x0a, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x1a, 0x7f,
0x0a, 0x07, 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, 0x14, 0x0a, 0x05, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x05, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x55, 0x52, 0x4c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x52, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x52, 0x4c, 0x12, 0x24, 0x0a, 0x05, 0x45, 0x72, 0x72,
0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x1a,
0x94, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05,
0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x6f, 0x6e,
0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x52,
0x4c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x55, 0x52, 0x4c, 0x12, 0x1e, 0x0a, 0x0a, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x49, 0x44, 0x12, 0x30, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x08, 0x52, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x70, 0x65, 0x65, 0x72,
0x69, 0x6e, 0x67, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e,
0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x22, 0x30, 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0a,
0x0a, 0x06, 0x55, 0x50, 0x53, 0x45, 0x52, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45,
0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x1a, 0x0c, 0x0a, 0x0a, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e,
0x61, 0x74, 0x65, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2a,
0x53, 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, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x41,
0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x41, 0x49, 0x4c, 0x49,
0x4e, 0x47, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54,
0x45, 0x44, 0x10, 0x04, 0x32, 0x94, 0x05, 0x0a, 0x0e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72,
0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 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, 0x1e, 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, 0x3f, 0x0a, 0x08, 0x49, 0x6e, 0x69, 0x74, 0x69,
0x61, 0x74, 0x65, 0x12, 0x18, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x49, 0x6e,
0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e,
0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72,
0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1b, 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, 0x1c, 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, 0x48, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73,
0x74, 0x12, 0x1b, 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, 0x1c,
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, 0x4e, 0x0a, 0x0d,
0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1d, 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, 0x1e, 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, 0x4b, 0x0a, 0x0c,
0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x1c, 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, 0x1d, 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, 0x6f, 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, 0x28, 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,
0x29, 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, 0x4f, 0x0a, 0x0f, 0x53, 0x74,
0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x2e,
0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1b, 0x2e, 0x70, 0x65, 0x65,
0x72, 0x69, 0x6e, 0x67, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x48, 0x00, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0a,
0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x26, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69,
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x54, 0x65,
0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0a, 0x74, 0x65, 0x72, 0x6d,
0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x1a, 0x7f, 0x0a, 0x07, 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, 0x14, 0x0a, 0x05, 0x4e, 0x6f, 0x6e,
0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12,
0x20, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x52, 0x4c, 0x18, 0x03,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x52,
0x4c, 0x12, 0x24, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x0e, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0x94, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x52, 0x4c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x52, 0x4c, 0x12, 0x1e, 0x0a, 0x0a,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0a, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x44, 0x12, 0x30, 0x0a, 0x08,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x41, 0x6e, 0x79, 0x52, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x4c,
0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28,
0x0e, 0x32, 0x2e, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x52, 0x65, 0x70, 0x6c,
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x30, 0x0a, 0x09,
0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b,
0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x53, 0x45, 0x52, 0x54,
0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x1a, 0x0c,
0x0a, 0x0a, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x42, 0x09, 0x0a, 0x07,
0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2a, 0x53, 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, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41,
0x4c, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12,
0x0b, 0x0a, 0x07, 0x46, 0x41, 0x49, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a,
0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, 0x10, 0x04, 0x32, 0x94, 0x05, 0x0a,
0x0e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
0x4e, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x12, 0x1d, 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,
0x1e, 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,
0x3f, 0x0a, 0x08, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x12, 0x18, 0x2e, 0x70, 0x65,
0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e,
0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x48, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x12,
0x1b, 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, 0x1c, 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, 0x48, 0x0a, 0x0b, 0x50, 0x65,
0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1b, 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, 0x1c, 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, 0x4e, 0x0a, 0x0d, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44,
0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1d, 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, 0x1e, 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, 0x4b, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57,
0x72, 0x69, 0x74, 0x65, 0x12, 0x1c, 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, 0x1d, 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, 0x6f, 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, 0x28, 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, 0x29, 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, 0x4f, 0x0a, 0x0f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e,
0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x1a, 0x1b, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x52, 0x65, 0x70,
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x28,
0x01, 0x30, 0x01, 0x42, 0x84, 0x01, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 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, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67,
0xca, 0x02, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0xe2, 0x02, 0x13, 0x50, 0x65, 0x65,
0x72, 0x69, 0x6e, 0x67, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0xea, 0x02, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x84, 0x01, 0x0a, 0x0b,
0x63, 0x6f, 0x6d, 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, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02,
0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0xca, 0x02, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69,
0x6e, 0x67, 0xe2, 0x02, 0x13, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x47, 0x50, 0x42,
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69,
0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@ -52,6 +52,12 @@ enum PeeringState {
}
// Peering defines a peering relationship between two disparate Consul clusters
//
// mog annotation:
//
// target=github.com/hashicorp/consul/api.Peering
// output=peering.gen.go
// name=API
message Peering {
// ID is a datacenter-scoped UUID for the peering.
// The ID is generated when a peering is first written to the state store.
@ -68,6 +74,8 @@ message Peering {
// State is one of the valid PeeringState values to represent the status of
// peering relationship.
//
// mog: func-to=PeeringStateToAPI func-from=PeeringStateFromAPI
PeeringState State = 4;
// PeerID is the ID that our peer assigned to this peering.
@ -210,6 +218,11 @@ message PeeringTrustBundleDeleteRequest {
message PeeringTrustBundleDeleteResponse {}
// mog annotation:
//
// target=github.com/hashicorp/consul/api.PeeringGenerateTokenRequest
// output=peering.gen.go
// name=API
message GenerateTokenRequest {
// Name of the remote peer.
string PeerName = 1;
@ -226,6 +239,11 @@ message GenerateTokenRequest {
map<string, string> Meta = 5;
}
// mog annotation:
//
// target=github.com/hashicorp/consul/api.PeeringGenerateTokenResponse
// output=peering.gen.go
// name=API
message GenerateTokenResponse {
// PeeringToken is an opaque string provided to the remote peer for it to complete
// the peering initialization handshake.
@ -233,6 +251,12 @@ message GenerateTokenResponse {
}
// @consul-rpc-glue: Datacenter
//
// mog annotation:
//
// target=github.com/hashicorp/consul/api.PeeringInitiateRequest
// output=peering.gen.go
// name=API
message InitiateRequest {
// Name of the remote peer.
string PeerName = 1;
@ -252,10 +276,13 @@ message InitiateRequest {
map<string, string> Meta = 6;
}
//
// mog annotation:
//
// target=github.com/hashicorp/consul/api.PeeringInitiateResponse
// output=peering.gen.go
// name=API
message InitiateResponse {
// this is just a placeholder to avoid returning google.protobuf.Empty
// (and consequently gogo.protobuf.types that it will be replaced with)
uint32 Status = 1;
}
message ReplicationMessage {