From dae47101fa4017d2f6ff135dc4015b963bc3b571 Mon Sep 17 00:00:00 2001 From: "R.B. Boyer" <4903+rboyer@users.noreply.github.com> Date: Wed, 25 May 2022 13:43:35 -0500 Subject: [PATCH] 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) --- .circleci/config.yml | 9 ++ GNUmakefile | 2 + agent/peering_endpoint.go | 108 ++++++++------ agent/peering_endpoint_test.go | 26 ++-- api/peering.go | 108 ++++++-------- api/peering_test.go | 216 +++++++++++++-------------- build-support/scripts/devtools.sh | 4 + proto/pbpeering/peering.gen.go | 100 +++++++++++++ proto/pbpeering/peering.go | 91 +++++++++++- proto/pbpeering/peering.pb.go | 237 ++++++++++++++++-------------- proto/pbpeering/peering.proto | 33 ++++- 11 files changed, 584 insertions(+), 350 deletions(-) create mode 100644 proto/pbpeering/peering.gen.go diff --git a/.circleci/config.yml b/.circleci/config.yml index fa2bb3379..e301448a5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -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: diff --git a/GNUmakefile b/GNUmakefile index fc951d0c5..35b21eae7 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -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 diff --git a/agent/peering_endpoint.go b/agent/peering_endpoint.go index 01a742b9a..569c8ca4a 100644 --- a/agent/peering_endpoint.go +++ b/agent/peering_endpoint.go @@ -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 } diff --git a/agent/peering_endpoint_test.go b/agent/peering_endpoint_test.go index fb441d136..ca90b1195 100644 --- a/agent/peering_endpoint_test.go +++ b/agent/peering_endpoint_test.go @@ -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) }) } diff --git a/api/peering.go b/api/peering.go index d2fc4f4a7..c0eefd3e4 100644 --- a/api/peering.go +++ b/api/peering.go @@ -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 { diff --git a/api/peering_test.go b/api/peering_test.go index 1437dd8f0..c93d17a24 100644 --- a/api/peering_test.go +++ b/api/peering_test.go @@ -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) + }) } diff --git a/build-support/scripts/devtools.sh b/build-support/scripts/devtools.sh index 4c2efea9d..0f3aeb691 100644 --- a/build-support/scripts/devtools.sh +++ b/build-support/scripts/devtools.sh @@ -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' \ diff --git a/proto/pbpeering/peering.gen.go b/proto/pbpeering/peering.gen.go new file mode 100644 index 000000000..1705edf89 --- /dev/null +++ b/proto/pbpeering/peering.gen.go @@ -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 +} diff --git a/proto/pbpeering/peering.go b/proto/pbpeering/peering.go index e55d9c180..b9da132f8 100644 --- a/proto/pbpeering/peering.go +++ b/proto/pbpeering/peering.go @@ -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 +} diff --git a/proto/pbpeering/peering.pb.go b/proto/pbpeering/peering.pb.go index 0259cc964..e4ed7a3a9 100644 --- a/proto/pbpeering/peering.pb.go +++ b/proto/pbpeering/peering.pb.go @@ -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 ( diff --git a/proto/pbpeering/peering.proto b/proto/pbpeering/peering.proto index 5eba1de4b..7ae75abed 100644 --- a/proto/pbpeering/peering.proto +++ b/proto/pbpeering/peering.proto @@ -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 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 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 {