Add ACL enforcement to peering endpoints
This commit is contained in:
parent
b60ebc022e
commit
5bbc0cc615
|
@ -335,6 +335,24 @@ func (a AllowAuthorizer) MeshWriteAllowed(ctx *AuthorizerContext) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// PeeringReadAllowed determines if the read-only Consul peering functions
|
||||
// can be used.
|
||||
func (a AllowAuthorizer) PeeringReadAllowed(ctx *AuthorizerContext) error {
|
||||
if a.Authorizer.PeeringRead(ctx) != Allow {
|
||||
return PermissionDeniedByACLUnnamed(a, ctx, ResourcePeering, AccessRead)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PeeringWriteAllowed determines if the state-changing Consul peering
|
||||
// functions can be used.
|
||||
func (a AllowAuthorizer) PeeringWriteAllowed(ctx *AuthorizerContext) error {
|
||||
if a.Authorizer.PeeringWrite(ctx) != Allow {
|
||||
return PermissionDeniedByACLUnnamed(a, ctx, ResourcePeering, AccessWrite)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NodeReadAllowed checks for permission to read (discover) a given node.
|
||||
func (a AllowAuthorizer) NodeReadAllowed(name string, ctx *AuthorizerContext) error {
|
||||
if a.Authorizer.NodeRead(name, ctx) != Allow {
|
||||
|
|
|
@ -3,16 +3,53 @@ package cachetype
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/hashstructure"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/hashicorp/consul/agent/cache"
|
||||
external "github.com/hashicorp/consul/agent/grpc-external"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/proto/pbpeering"
|
||||
)
|
||||
|
||||
// Recommended name for registration.
|
||||
const TrustBundleReadName = "peer-trust-bundle"
|
||||
|
||||
type TrustBundleReadRequest struct {
|
||||
Request *pbpeering.TrustBundleReadRequest
|
||||
structs.QueryOptions
|
||||
}
|
||||
|
||||
func (r *TrustBundleReadRequest) CacheInfo() cache.RequestInfo {
|
||||
info := cache.RequestInfo{
|
||||
Token: r.Token,
|
||||
Datacenter: "",
|
||||
MinIndex: 0,
|
||||
Timeout: 0,
|
||||
MustRevalidate: false,
|
||||
|
||||
// OPTIMIZE(peering): Cache.notifyPollingQuery polls at this interval. We need to revisit how that polling works.
|
||||
// Using an exponential backoff when the result hasn't changed may be preferable.
|
||||
MaxAge: 1 * time.Second,
|
||||
}
|
||||
|
||||
v, err := hashstructure.Hash([]interface{}{
|
||||
r.Request.Partition,
|
||||
r.Request.Name,
|
||||
}, nil)
|
||||
if err == nil {
|
||||
// If there is an error, we don't set the key. A blank key forces
|
||||
// no cache for this request so the request is forwarded directly
|
||||
// to the server.
|
||||
info.Key = strconv.FormatUint(v, 10)
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
// TrustBundle supports fetching discovering service instances via prepared
|
||||
// queries.
|
||||
type TrustBundle struct {
|
||||
|
@ -33,14 +70,20 @@ func (t *TrustBundle) Fetch(_ cache.FetchOptions, req cache.Request) (cache.Fetc
|
|||
// The request should be a TrustBundleReadRequest.
|
||||
// We do not need to make a copy of this request type like in other cache types
|
||||
// because the RequestInfo is synthetic.
|
||||
reqReal, ok := req.(*pbpeering.TrustBundleReadRequest)
|
||||
reqReal, ok := req.(*TrustBundleReadRequest)
|
||||
if !ok {
|
||||
return result, fmt.Errorf(
|
||||
"Internal cache failure: request wrong type: %T", req)
|
||||
}
|
||||
|
||||
// Always allow stale - there's no point in hitting leader if the request is
|
||||
// going to be served from cache and end up arbitrarily stale anyway. This
|
||||
// allows cached service-discover to automatically read scale across all
|
||||
// servers too.
|
||||
reqReal.QueryOptions.SetAllowStale(true)
|
||||
|
||||
// Fetch
|
||||
reply, err := t.Client.TrustBundleRead(context.Background(), reqReal)
|
||||
reply, err := t.Client.TrustBundleRead(external.ContextWithToken(context.Background(), reqReal.Token), reqReal.Request)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
|
|
@ -33,8 +33,10 @@ func TestTrustBundle(t *testing.T) {
|
|||
Return(resp, nil)
|
||||
|
||||
// Fetch and assert against the result.
|
||||
result, err := typ.Fetch(cache.FetchOptions{}, &pbpeering.TrustBundleReadRequest{
|
||||
result, err := typ.Fetch(cache.FetchOptions{}, &TrustBundleReadRequest{
|
||||
Request: &pbpeering.TrustBundleReadRequest{
|
||||
Name: "foo",
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, cache.FetchResult{
|
||||
|
@ -82,7 +84,9 @@ func TestTrustBundle_MultipleUpdates(t *testing.T) {
|
|||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := c.Notify(ctx, TrustBundleReadName, &pbpeering.TrustBundleReadRequest{Name: "foo"}, "updates", ch)
|
||||
err := c.Notify(ctx, TrustBundleReadName, &TrustBundleReadRequest{
|
||||
Request: &pbpeering.TrustBundleReadRequest{Name: "foo"},
|
||||
}, "updates", ch)
|
||||
require.NoError(t, err)
|
||||
|
||||
i := uint64(1)
|
||||
|
|
|
@ -3,16 +3,55 @@ package cachetype
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/hashstructure"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/hashicorp/consul/agent/cache"
|
||||
external "github.com/hashicorp/consul/agent/grpc-external"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/proto/pbpeering"
|
||||
)
|
||||
|
||||
// Recommended name for registration.
|
||||
const TrustBundleListName = "trust-bundles"
|
||||
|
||||
type TrustBundleListRequest struct {
|
||||
Request *pbpeering.TrustBundleListByServiceRequest
|
||||
structs.QueryOptions
|
||||
}
|
||||
|
||||
func (r *TrustBundleListRequest) CacheInfo() cache.RequestInfo {
|
||||
info := cache.RequestInfo{
|
||||
Token: r.Token,
|
||||
Datacenter: "",
|
||||
MinIndex: 0,
|
||||
Timeout: 0,
|
||||
MustRevalidate: false,
|
||||
|
||||
// OPTIMIZE(peering): Cache.notifyPollingQuery polls at this interval. We need to revisit how that polling works.
|
||||
// Using an exponential backoff when the result hasn't changed may be preferable.
|
||||
MaxAge: 1 * time.Second,
|
||||
}
|
||||
|
||||
v, err := hashstructure.Hash([]interface{}{
|
||||
r.Request.Partition,
|
||||
r.Request.Namespace,
|
||||
r.Request.ServiceName,
|
||||
r.Request.Kind,
|
||||
}, nil)
|
||||
if err == nil {
|
||||
// If there is an error, we don't set the key. A blank key forces
|
||||
// no cache for this request so the request is forwarded directly
|
||||
// to the server.
|
||||
info.Key = strconv.FormatUint(v, 10)
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
// TrustBundles supports fetching discovering service instances via prepared
|
||||
// queries.
|
||||
type TrustBundles struct {
|
||||
|
@ -30,17 +69,23 @@ type TrustBundleLister interface {
|
|||
func (t *TrustBundles) Fetch(_ cache.FetchOptions, req cache.Request) (cache.FetchResult, error) {
|
||||
var result cache.FetchResult
|
||||
|
||||
// The request should be a TrustBundleListByServiceRequest.
|
||||
// The request should be a TrustBundleListRequest.
|
||||
// We do not need to make a copy of this request type like in other cache types
|
||||
// because the RequestInfo is synthetic.
|
||||
reqReal, ok := req.(*pbpeering.TrustBundleListByServiceRequest)
|
||||
reqReal, ok := req.(*TrustBundleListRequest)
|
||||
if !ok {
|
||||
return result, fmt.Errorf(
|
||||
"Internal cache failure: request wrong type: %T", req)
|
||||
}
|
||||
|
||||
// Always allow stale - there's no point in hitting leader if the request is
|
||||
// going to be served from cache and end up arbitrarily stale anyway. This
|
||||
// allows cached service-discover to automatically read scale across all
|
||||
// servers too.
|
||||
reqReal.QueryOptions.SetAllowStale(true)
|
||||
|
||||
// Fetch
|
||||
reply, err := t.Client.TrustBundleListByService(context.Background(), reqReal)
|
||||
reply, err := t.Client.TrustBundleListByService(external.ContextWithToken(context.Background(), reqReal.Token), reqReal.Request)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
|
|
@ -36,8 +36,10 @@ func TestTrustBundles(t *testing.T) {
|
|||
Return(resp, nil)
|
||||
|
||||
// Fetch and assert against the result.
|
||||
result, err := typ.Fetch(cache.FetchOptions{}, &pbpeering.TrustBundleListByServiceRequest{
|
||||
result, err := typ.Fetch(cache.FetchOptions{}, &TrustBundleListRequest{
|
||||
Request: &pbpeering.TrustBundleListByServiceRequest{
|
||||
ServiceName: "foo",
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, cache.FetchResult{
|
||||
|
@ -85,7 +87,9 @@ func TestTrustBundles_MultipleUpdates(t *testing.T) {
|
|||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
err := c.Notify(ctx, TrustBundleListName, &pbpeering.TrustBundleListByServiceRequest{ServiceName: "foo"}, "updates", ch)
|
||||
err := c.Notify(ctx, TrustBundleListName, &TrustBundleListRequest{
|
||||
Request: &pbpeering.TrustBundleListByServiceRequest{ServiceName: "foo"},
|
||||
}, "updates", ch)
|
||||
require.NoError(t, err)
|
||||
|
||||
i := uint64(1)
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/acl/resolver"
|
||||
"github.com/hashicorp/consul/agent/consul/stream"
|
||||
"github.com/hashicorp/consul/agent/grpc-external/services/peerstream"
|
||||
"github.com/hashicorp/consul/agent/rpc/peering"
|
||||
|
@ -160,3 +162,7 @@ func (b *PeeringBackend) CatalogDeregister(req *structs.DeregisterRequest) error
|
|||
_, err := b.srv.leaderRaftApply("Catalog.Deregister", structs.DeregisterRequestType, req)
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *PeeringBackend) ResolveTokenAndDefaultMeta(token string, entMeta *acl.EnterpriseMeta, authzCtx *acl.AuthorizerContext) (resolver.Result, error) {
|
||||
return b.srv.ResolveTokenAndDefaultMeta(token, entMeta, authzCtx)
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@ func TestPeeringBackend_RejectsPartition(t *testing.T) {
|
|||
peeringClient := pbpeering.NewPeeringServiceClient(conn)
|
||||
|
||||
req := pbpeering.GenerateTokenRequest{
|
||||
Datacenter: "dc1",
|
||||
Partition: "test",
|
||||
}
|
||||
_, err = peeringClient.GenerateToken(ctx, &req)
|
||||
|
@ -77,7 +76,6 @@ func TestPeeringBackend_IgnoresDefaultPartition(t *testing.T) {
|
|||
peeringClient := pbpeering.NewPeeringServiceClient(conn)
|
||||
|
||||
req := pbpeering.GenerateTokenRequest{
|
||||
Datacenter: "dc1",
|
||||
PeerName: "my-peer",
|
||||
Partition: "DeFaUlT",
|
||||
}
|
||||
|
|
|
@ -15,43 +15,6 @@ import (
|
|||
"github.com/hashicorp/consul/testrpc"
|
||||
)
|
||||
|
||||
func TestPeeringBackend_DoesNotForwardToDifferentDC(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("too slow for testing.Short")
|
||||
}
|
||||
|
||||
t.Parallel()
|
||||
_, s1 := testServerDC(t, "dc1")
|
||||
_, s2 := testServerDC(t, "dc2")
|
||||
|
||||
joinWAN(t, s2, s1)
|
||||
|
||||
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
||||
testrpc.WaitForLeader(t, s2.RPC, "dc2")
|
||||
|
||||
// make a grpc client to dial s2 directly
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
conn, err := gogrpc.DialContext(ctx, s2.config.RPCAddr.String(),
|
||||
gogrpc.WithContextDialer(newServerDialer(s2.config.RPCAddr.String())),
|
||||
gogrpc.WithInsecure(),
|
||||
gogrpc.WithBlock())
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { conn.Close() })
|
||||
|
||||
peeringClient := pbpeering.NewPeeringServiceClient(conn)
|
||||
|
||||
// GenerateToken request should fail against dc1, because we are dialing dc2. The GenerateToken request should never be forwarded across datacenters.
|
||||
req := pbpeering.GenerateTokenRequest{
|
||||
PeerName: "peer1-usw1",
|
||||
Datacenter: "dc1",
|
||||
}
|
||||
_, err = peeringClient.GenerateToken(ctx, &req)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "requests to generate peering tokens cannot be forwarded to remote datacenters")
|
||||
}
|
||||
|
||||
func TestPeeringBackend_ForwardToLeader(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -86,7 +49,6 @@ func TestPeeringBackend_ForwardToLeader(t *testing.T) {
|
|||
testutil.RunStep(t, "forward a write", func(t *testing.T) {
|
||||
// Do the grpc Write call to server2
|
||||
req := pbpeering.GenerateTokenRequest{
|
||||
Datacenter: "dc1",
|
||||
PeerName: "foo",
|
||||
}
|
||||
_, err := peeringClient.GenerateToken(ctx, &req)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
external "github.com/hashicorp/consul/agent/grpc-external"
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
"github.com/hashicorp/consul/proto/pbpeering"
|
||||
|
@ -32,17 +33,20 @@ 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 string) (interface{}, error) {
|
||||
args := pbpeering.PeeringReadRequest{
|
||||
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()
|
||||
args := pbpeering.PeeringReadRequest{
|
||||
Name: name,
|
||||
Partition: entMeta.PartitionOrEmpty(),
|
||||
}
|
||||
|
||||
result, err := s.agent.rpcClientPeering.PeeringRead(req.Context(), &args)
|
||||
var token string
|
||||
s.parseToken(req, &token)
|
||||
ctx := external.ContextWithToken(req.Context(), token)
|
||||
|
||||
result, err := s.agent.rpcClientPeering.PeeringRead(ctx, &args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -55,16 +59,19 @@ func (s *HTTPHandlers) peeringRead(resp http.ResponseWriter, req *http.Request,
|
|||
|
||||
// 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) {
|
||||
args := pbpeering.PeeringListRequest{
|
||||
Datacenter: s.agent.config.Datacenter,
|
||||
}
|
||||
var entMeta acl.EnterpriseMeta
|
||||
if err := s.parseEntMetaPartition(req, &entMeta); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
args.Partition = entMeta.PartitionOrEmpty()
|
||||
args := pbpeering.PeeringListRequest{
|
||||
Partition: entMeta.PartitionOrEmpty(),
|
||||
}
|
||||
|
||||
pbresp, err := s.agent.rpcClientPeering.PeeringList(req.Context(), &args)
|
||||
var token string
|
||||
s.parseToken(req, &token)
|
||||
ctx := external.ContextWithToken(req.Context(), token)
|
||||
|
||||
pbresp, err := s.agent.rpcClientPeering.PeeringList(ctx, &args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -79,14 +86,12 @@ func (s *HTTPHandlers) PeeringGenerateToken(resp http.ResponseWriter, req *http.
|
|||
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "The peering arguments must be provided in the body"}
|
||||
}
|
||||
|
||||
apiRequest := &api.PeeringGenerateTokenRequest{
|
||||
Datacenter: s.agent.config.Datacenter,
|
||||
}
|
||||
if err := lib.DecodeJSON(req.Body, apiRequest); err != nil {
|
||||
var apiRequest api.PeeringGenerateTokenRequest
|
||||
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)
|
||||
|
||||
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."}
|
||||
}
|
||||
|
@ -99,7 +104,11 @@ func (s *HTTPHandlers) PeeringGenerateToken(resp http.ResponseWriter, req *http.
|
|||
args.Partition = entMeta.PartitionOrEmpty()
|
||||
}
|
||||
|
||||
out, err := s.agent.rpcClientPeering.GenerateToken(req.Context(), args)
|
||||
var token string
|
||||
s.parseToken(req, &token)
|
||||
ctx := external.ContextWithToken(req.Context(), token)
|
||||
|
||||
out, err := s.agent.rpcClientPeering.GenerateToken(ctx, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -114,18 +123,15 @@ func (s *HTTPHandlers) PeeringEstablish(resp http.ResponseWriter, req *http.Requ
|
|||
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "The peering arguments must be provided in the body"}
|
||||
}
|
||||
|
||||
apiRequest := &api.PeeringEstablishRequest{
|
||||
Datacenter: s.agent.config.Datacenter,
|
||||
}
|
||||
if err := lib.DecodeJSON(req.Body, apiRequest); err != nil {
|
||||
var apiRequest api.PeeringEstablishRequest
|
||||
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.NewEstablishRequestFromAPI(apiRequest)
|
||||
|
||||
args := pbpeering.NewEstablishRequestFromAPI(&apiRequest)
|
||||
if args.PeerName == "" {
|
||||
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "PeerName is required in the payload when establishing a peering."}
|
||||
}
|
||||
|
||||
if args.PeeringToken == "" {
|
||||
return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "PeeringToken is required in the payload when establishing a peering."}
|
||||
}
|
||||
|
@ -138,7 +144,11 @@ func (s *HTTPHandlers) PeeringEstablish(resp http.ResponseWriter, req *http.Requ
|
|||
args.Partition = entMeta.PartitionOrEmpty()
|
||||
}
|
||||
|
||||
out, err := s.agent.rpcClientPeering.Establish(req.Context(), args)
|
||||
var token string
|
||||
s.parseToken(req, &token)
|
||||
ctx := external.ContextWithToken(req.Context(), token)
|
||||
|
||||
out, err := s.agent.rpcClientPeering.Establish(ctx, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -149,17 +159,20 @@ func (s *HTTPHandlers) PeeringEstablish(resp http.ResponseWriter, req *http.Requ
|
|||
// 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()
|
||||
args := pbpeering.PeeringDeleteRequest{
|
||||
Name: name,
|
||||
Partition: entMeta.PartitionOrEmpty(),
|
||||
}
|
||||
|
||||
_, err := s.agent.rpcClientPeering.PeeringDelete(req.Context(), &args)
|
||||
var token string
|
||||
s.parseToken(req, &token)
|
||||
ctx := external.ContextWithToken(req.Context(), token)
|
||||
|
||||
_, err := s.agent.rpcClientPeering.PeeringDelete(ctx, &args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package proxycfgglue
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/consul/proto/pbpeering"
|
||||
"github.com/hashicorp/go-memdb"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
|
@ -14,7 +15,6 @@ import (
|
|||
"github.com/hashicorp/consul/agent/consul/watch"
|
||||
"github.com/hashicorp/consul/agent/proxycfg"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/proto/pbpeering"
|
||||
)
|
||||
|
||||
// Store is the state store interface required for server-local data sources.
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
// CacheTrustBundle satisfies the proxycfg.TrustBundle interface by sourcing
|
||||
// data from the agent cache.
|
||||
func CacheTrustBundle(c *cache.Cache) proxycfg.TrustBundle {
|
||||
return &cacheProxyDataSource[*pbpeering.TrustBundleReadRequest]{c, cachetype.TrustBundleReadName}
|
||||
return &cacheProxyDataSource[*cachetype.TrustBundleReadRequest]{c, cachetype.TrustBundleReadName}
|
||||
}
|
||||
|
||||
// ServerTrustBundle satisfies the proxycfg.TrustBundle interface by sourcing
|
||||
|
@ -32,13 +32,13 @@ type serverTrustBundle struct {
|
|||
deps ServerDataSourceDeps
|
||||
}
|
||||
|
||||
func (s *serverTrustBundle) Notify(ctx context.Context, req *pbpeering.TrustBundleReadRequest, correlationID string, ch chan<- proxycfg.UpdateEvent) error {
|
||||
func (s *serverTrustBundle) Notify(ctx context.Context, req *cachetype.TrustBundleReadRequest, correlationID string, ch chan<- proxycfg.UpdateEvent) error {
|
||||
// TODO(peering): ACL check.
|
||||
return watch.ServerLocalNotify(ctx, correlationID, s.deps.GetStore,
|
||||
func(ws memdb.WatchSet, store Store) (uint64, *pbpeering.TrustBundleReadResponse, error) {
|
||||
index, bundle, err := store.PeeringTrustBundleRead(ws, state.Query{
|
||||
Value: req.Name,
|
||||
EnterpriseMeta: *structs.NodeEnterpriseMetaInPartition(req.Partition),
|
||||
Value: req.Request.Name,
|
||||
EnterpriseMeta: *structs.NodeEnterpriseMetaInPartition(req.Request.Partition),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
|
@ -55,7 +55,7 @@ func (s *serverTrustBundle) Notify(ctx context.Context, req *pbpeering.TrustBund
|
|||
// CacheTrustBundleList satisfies the proxycfg.TrustBundleList interface by sourcing
|
||||
// data from the agent cache.
|
||||
func CacheTrustBundleList(c *cache.Cache) proxycfg.TrustBundleList {
|
||||
return &cacheProxyDataSource[*pbpeering.TrustBundleListByServiceRequest]{c, cachetype.TrustBundleListName}
|
||||
return &cacheProxyDataSource[*cachetype.TrustBundleListRequest]{c, cachetype.TrustBundleListName}
|
||||
}
|
||||
|
||||
// ServerTrustBundleList satisfies the proxycfg.TrustBundle interface by
|
||||
|
@ -68,8 +68,8 @@ type serverTrustBundleList struct {
|
|||
deps ServerDataSourceDeps
|
||||
}
|
||||
|
||||
func (s *serverTrustBundleList) Notify(ctx context.Context, req *pbpeering.TrustBundleListByServiceRequest, correlationID string, ch chan<- proxycfg.UpdateEvent) error {
|
||||
entMeta := acl.NewEnterpriseMetaWithPartition(req.Partition, req.Namespace)
|
||||
func (s *serverTrustBundleList) Notify(ctx context.Context, req *cachetype.TrustBundleListRequest, correlationID string, ch chan<- proxycfg.UpdateEvent) error {
|
||||
entMeta := acl.NewEnterpriseMetaWithPartition(req.Request.Partition, req.Request.Namespace)
|
||||
|
||||
// TODO(peering): ACL check.
|
||||
return watch.ServerLocalNotify(ctx, correlationID, s.deps.GetStore,
|
||||
|
@ -80,11 +80,11 @@ func (s *serverTrustBundleList) Notify(ctx context.Context, req *pbpeering.Trust
|
|||
err error
|
||||
)
|
||||
switch {
|
||||
case req.ServiceName != "":
|
||||
index, bundles, err = store.TrustBundleListByService(ws, req.ServiceName, s.deps.Datacenter, entMeta)
|
||||
case req.Kind == string(structs.ServiceKindMeshGateway):
|
||||
case req.Request.Kind == string(structs.ServiceKindMeshGateway):
|
||||
index, bundles, err = store.PeeringTrustBundleList(ws, entMeta)
|
||||
case req.Kind != "":
|
||||
case req.Request.ServiceName != "":
|
||||
index, bundles, err = store.TrustBundleListByService(ws, req.Request.ServiceName, s.deps.Datacenter, entMeta)
|
||||
case req.Request.Kind != "":
|
||||
err = errors.New("kind must be mesh-gateway if set")
|
||||
default:
|
||||
err = errors.New("one of service or kind is required")
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
cachetype "github.com/hashicorp/consul/agent/cache-types"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/agent/consul/state"
|
||||
|
@ -32,8 +33,10 @@ func TestServerTrustBundle(t *testing.T) {
|
|||
})
|
||||
|
||||
eventCh := make(chan proxycfg.UpdateEvent)
|
||||
err := dataSource.Notify(context.Background(), &pbpeering.TrustBundleReadRequest{
|
||||
err := dataSource.Notify(context.Background(), &cachetype.TrustBundleReadRequest{
|
||||
Request: &pbpeering.TrustBundleReadRequest{
|
||||
Name: peerName,
|
||||
},
|
||||
}, "", eventCh)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -96,9 +99,11 @@ func TestServerTrustBundleList(t *testing.T) {
|
|||
})
|
||||
|
||||
eventCh := make(chan proxycfg.UpdateEvent)
|
||||
err := dataSource.Notify(context.Background(), &pbpeering.TrustBundleListByServiceRequest{
|
||||
err := dataSource.Notify(context.Background(), &cachetype.TrustBundleListRequest{
|
||||
Request: &pbpeering.TrustBundleListByServiceRequest{
|
||||
ServiceName: serviceName,
|
||||
Partition: us,
|
||||
},
|
||||
}, "", eventCh)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -134,9 +139,11 @@ func TestServerTrustBundleList(t *testing.T) {
|
|||
})
|
||||
|
||||
eventCh := make(chan proxycfg.UpdateEvent)
|
||||
err := dataSource.Notify(context.Background(), &pbpeering.TrustBundleListByServiceRequest{
|
||||
err := dataSource.Notify(context.Background(), &cachetype.TrustBundleListRequest{
|
||||
Request: &pbpeering.TrustBundleListByServiceRequest{
|
||||
Kind: string(structs.ServiceKindMeshGateway),
|
||||
Partition: "default",
|
||||
},
|
||||
}, "", eventCh)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
|
|
@ -46,11 +46,13 @@ func (s *handlerConnectProxy) initialize(ctx context.Context) (ConfigSnapshot, e
|
|||
return snap, err
|
||||
}
|
||||
|
||||
err = s.dataSources.TrustBundleList.Notify(ctx, &pbpeering.TrustBundleListByServiceRequest{
|
||||
// TODO(peering): Pass ACL token
|
||||
err = s.dataSources.TrustBundleList.Notify(ctx, &cachetype.TrustBundleListRequest{
|
||||
Request: &pbpeering.TrustBundleListByServiceRequest{
|
||||
ServiceName: s.proxyCfg.DestinationServiceName,
|
||||
Namespace: s.proxyID.NamespaceOrDefault(),
|
||||
Partition: s.proxyID.PartitionOrDefault(),
|
||||
},
|
||||
QueryOptions: structs.QueryOptions{Token: s.token},
|
||||
}, peeringTrustBundlesWatchID, s.ch)
|
||||
if err != nil {
|
||||
return snap, err
|
||||
|
@ -226,9 +228,12 @@ func (s *handlerConnectProxy) initialize(ctx context.Context) (ConfigSnapshot, e
|
|||
// Check whether a watch for this peer exists to avoid duplicates.
|
||||
if ok := snap.ConnectProxy.UpstreamPeerTrustBundles.IsWatched(uid.Peer); !ok {
|
||||
peerCtx, cancel := context.WithCancel(ctx)
|
||||
if err := s.dataSources.TrustBundle.Notify(peerCtx, &pbpeering.TrustBundleReadRequest{
|
||||
if err := s.dataSources.TrustBundle.Notify(peerCtx, &cachetype.TrustBundleReadRequest{
|
||||
Request: &pbpeering.TrustBundleReadRequest{
|
||||
Name: uid.Peer,
|
||||
Partition: uid.PartitionOrDefault(),
|
||||
},
|
||||
QueryOptions: structs.QueryOptions{Token: s.token},
|
||||
}, peerTrustBundleIDPrefix+uid.Peer, s.ch); err != nil {
|
||||
cancel()
|
||||
return snap, fmt.Errorf("error while watching trust bundle for peer %q: %w", uid.Peer, err)
|
||||
|
@ -344,9 +349,12 @@ func (s *handlerConnectProxy) handleUpdate(ctx context.Context, u UpdateEvent, s
|
|||
// Check whether a watch for this peer exists to avoid duplicates.
|
||||
if ok := snap.ConnectProxy.UpstreamPeerTrustBundles.IsWatched(uid.Peer); !ok {
|
||||
peerCtx, cancel := context.WithCancel(ctx)
|
||||
if err := s.dataSources.TrustBundle.Notify(peerCtx, &pbpeering.TrustBundleReadRequest{
|
||||
if err := s.dataSources.TrustBundle.Notify(peerCtx, &cachetype.TrustBundleReadRequest{
|
||||
Request: &pbpeering.TrustBundleReadRequest{
|
||||
Name: uid.Peer,
|
||||
Partition: uid.PartitionOrDefault(),
|
||||
},
|
||||
QueryOptions: structs.QueryOptions{Token: s.token},
|
||||
}, peerTrustBundleIDPrefix+uid.Peer, s.ch); err != nil {
|
||||
cancel()
|
||||
return fmt.Errorf("error while watching trust bundle for peer %q: %w", uid.Peer, err)
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
cachetype "github.com/hashicorp/consul/agent/cache-types"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/proto/pbpeering"
|
||||
)
|
||||
|
||||
// UpdateEvent contains new data for a resource we are subscribed to (e.g. an
|
||||
|
@ -220,13 +219,13 @@ type ServiceList interface {
|
|||
// TrustBundle is the interface used to consume updates about a single
|
||||
// peer's trust bundle.
|
||||
type TrustBundle interface {
|
||||
Notify(ctx context.Context, req *pbpeering.TrustBundleReadRequest, correlationID string, ch chan<- UpdateEvent) error
|
||||
Notify(ctx context.Context, req *cachetype.TrustBundleReadRequest, correlationID string, ch chan<- UpdateEvent) error
|
||||
}
|
||||
|
||||
// TrustBundleList is the interface used to consume updates about trust bundles
|
||||
// for peered clusters that the given proxy is exported to.
|
||||
type TrustBundleList interface {
|
||||
Notify(ctx context.Context, req *pbpeering.TrustBundleListByServiceRequest, correlationID string, ch chan<- UpdateEvent) error
|
||||
Notify(ctx context.Context, req *cachetype.TrustBundleListRequest, correlationID string, ch chan<- UpdateEvent) error
|
||||
}
|
||||
|
||||
// ExportedPeeredServices is the interface used to consume updates about the
|
||||
|
|
|
@ -32,11 +32,14 @@ func (s *handlerMeshGateway) initialize(ctx context.Context) (ConfigSnapshot, er
|
|||
}
|
||||
|
||||
// Watch for all peer trust bundles we may need.
|
||||
err = s.dataSources.TrustBundleList.Notify(ctx, &pbpeering.TrustBundleListByServiceRequest{
|
||||
// TODO(peering): Pass ACL token
|
||||
err = s.dataSources.TrustBundleList.Notify(ctx, &cachetype.TrustBundleListRequest{
|
||||
Request: &pbpeering.TrustBundleListByServiceRequest{
|
||||
Kind: string(structs.ServiceKindMeshGateway),
|
||||
ServiceName: s.service,
|
||||
Namespace: s.proxyID.NamespaceOrDefault(),
|
||||
Partition: s.proxyID.PartitionOrDefault(),
|
||||
},
|
||||
QueryOptions: structs.QueryOptions{Token: s.token},
|
||||
}, peeringTrustBundlesWatchID, s.ch)
|
||||
if err != nil {
|
||||
return snap, err
|
||||
|
|
|
@ -137,8 +137,8 @@ func recordWatches(sc *stateConfig) *watchRecorder {
|
|||
PreparedQuery: typedWatchRecorder[*structs.PreparedQueryExecuteRequest]{wr},
|
||||
ResolvedServiceConfig: typedWatchRecorder[*structs.ServiceConfigRequest]{wr},
|
||||
ServiceList: typedWatchRecorder[*structs.DCSpecificRequest]{wr},
|
||||
TrustBundle: typedWatchRecorder[*pbpeering.TrustBundleReadRequest]{wr},
|
||||
TrustBundleList: typedWatchRecorder[*pbpeering.TrustBundleListByServiceRequest]{wr},
|
||||
TrustBundle: typedWatchRecorder[*cachetype.TrustBundleReadRequest]{wr},
|
||||
TrustBundleList: typedWatchRecorder[*cachetype.TrustBundleListRequest]{wr},
|
||||
ExportedPeeredServices: typedWatchRecorder[*structs.DCSpecificRequest]{wr},
|
||||
}
|
||||
recordWatchesEnterprise(sc, wr)
|
||||
|
@ -203,9 +203,9 @@ func verifyDatacentersWatch(t testing.TB, request any) {
|
|||
|
||||
func genVerifyTrustBundleReadWatch(peer string) verifyWatchRequest {
|
||||
return func(t testing.TB, request any) {
|
||||
reqReal, ok := request.(*pbpeering.TrustBundleReadRequest)
|
||||
reqReal, ok := request.(*cachetype.TrustBundleReadRequest)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, peer, reqReal.Name)
|
||||
require.Equal(t, peer, reqReal.Request.Name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,19 +225,19 @@ func genVerifyLeafWatch(expectedService string, expectedDatacenter string) verif
|
|||
|
||||
func genVerifyTrustBundleListWatch(service string) verifyWatchRequest {
|
||||
return func(t testing.TB, request any) {
|
||||
reqReal, ok := request.(*pbpeering.TrustBundleListByServiceRequest)
|
||||
reqReal, ok := request.(*cachetype.TrustBundleListRequest)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, service, reqReal.ServiceName)
|
||||
require.Equal(t, service, reqReal.Request.ServiceName)
|
||||
}
|
||||
}
|
||||
|
||||
func genVerifyTrustBundleListWatchForMeshGateway(partition string) verifyWatchRequest {
|
||||
return func(t testing.TB, request any) {
|
||||
reqReal, ok := request.(*pbpeering.TrustBundleListByServiceRequest)
|
||||
reqReal, ok := request.(*cachetype.TrustBundleListRequest)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, string(structs.ServiceKindMeshGateway), reqReal.Kind)
|
||||
require.True(t, acl.EqualPartitions(partition, reqReal.Partition), "%q != %q", partition, reqReal.Partition)
|
||||
require.Empty(t, reqReal.ServiceName)
|
||||
require.Equal(t, string(structs.ServiceKindMeshGateway), reqReal.Request.Kind)
|
||||
require.True(t, acl.EqualPartitions(partition, reqReal.Request.Partition), "%q != %q", partition, reqReal.Request.Partition)
|
||||
require.NotEmpty(t, reqReal.Request.ServiceName)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -751,8 +751,8 @@ func testConfigSnapshotFixture(
|
|||
PreparedQuery: &noopDataSource[*structs.PreparedQueryExecuteRequest]{},
|
||||
ResolvedServiceConfig: &noopDataSource[*structs.ServiceConfigRequest]{},
|
||||
ServiceList: &noopDataSource[*structs.DCSpecificRequest]{},
|
||||
TrustBundle: &noopDataSource[*pbpeering.TrustBundleReadRequest]{},
|
||||
TrustBundleList: &noopDataSource[*pbpeering.TrustBundleListByServiceRequest]{},
|
||||
TrustBundle: &noopDataSource[*cachetype.TrustBundleReadRequest]{},
|
||||
TrustBundleList: &noopDataSource[*cachetype.TrustBundleListRequest]{},
|
||||
ExportedPeeredServices: &noopDataSource[*structs.DCSpecificRequest]{},
|
||||
},
|
||||
dnsConfig: DNSConfig{ // TODO: make configurable
|
||||
|
@ -954,8 +954,8 @@ func NewTestDataSources() *TestDataSources {
|
|||
PreparedQuery: NewTestDataSource[*structs.PreparedQueryExecuteRequest, *structs.PreparedQueryExecuteResponse](),
|
||||
ResolvedServiceConfig: NewTestDataSource[*structs.ServiceConfigRequest, *structs.ServiceConfigResponse](),
|
||||
ServiceList: NewTestDataSource[*structs.DCSpecificRequest, *structs.IndexedServiceList](),
|
||||
TrustBundle: NewTestDataSource[*pbpeering.TrustBundleReadRequest, *pbpeering.TrustBundleReadResponse](),
|
||||
TrustBundleList: NewTestDataSource[*pbpeering.TrustBundleListByServiceRequest, *pbpeering.TrustBundleListByServiceResponse](),
|
||||
TrustBundle: NewTestDataSource[*cachetype.TrustBundleReadRequest, *pbpeering.TrustBundleReadResponse](),
|
||||
TrustBundleList: NewTestDataSource[*cachetype.TrustBundleListRequest, *pbpeering.TrustBundleListByServiceResponse](),
|
||||
}
|
||||
srcs.buildEnterpriseSources()
|
||||
return srcs
|
||||
|
@ -981,8 +981,8 @@ type TestDataSources struct {
|
|||
PreparedQuery *TestDataSource[*structs.PreparedQueryExecuteRequest, *structs.PreparedQueryExecuteResponse]
|
||||
ResolvedServiceConfig *TestDataSource[*structs.ServiceConfigRequest, *structs.ServiceConfigResponse]
|
||||
ServiceList *TestDataSource[*structs.DCSpecificRequest, *structs.IndexedServiceList]
|
||||
TrustBundle *TestDataSource[*pbpeering.TrustBundleReadRequest, *pbpeering.TrustBundleReadResponse]
|
||||
TrustBundleList *TestDataSource[*pbpeering.TrustBundleListByServiceRequest, *pbpeering.TrustBundleListByServiceResponse]
|
||||
TrustBundle *TestDataSource[*cachetype.TrustBundleReadRequest, *pbpeering.TrustBundleReadResponse]
|
||||
TrustBundleList *TestDataSource[*cachetype.TrustBundleListRequest, *pbpeering.TrustBundleListByServiceResponse]
|
||||
|
||||
TestDataSourcesEnterprise
|
||||
}
|
||||
|
|
|
@ -16,9 +16,11 @@ import (
|
|||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/acl/resolver"
|
||||
"github.com/hashicorp/consul/agent/consul/state"
|
||||
"github.com/hashicorp/consul/agent/consul/stream"
|
||||
"github.com/hashicorp/consul/agent/dns"
|
||||
external "github.com/hashicorp/consul/agent/grpc-external"
|
||||
"github.com/hashicorp/consul/agent/grpc-external/services/peerstream"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
|
@ -43,6 +45,20 @@ func (e *errPeeringInvalidServerAddress) Error() string {
|
|||
return fmt.Sprintf("%s is not a valid peering server address", e.addr)
|
||||
}
|
||||
|
||||
// For private/internal gRPC handlers, protoc-gen-rpc-glue generates the
|
||||
// requisite methods to satisfy the structs.RPCInfo interface using fields
|
||||
// from the pbcommon package. This service is public, so we can't use those
|
||||
// fields in our proto definition. Instead, we construct our RPCInfo manually.
|
||||
var writeRequest struct {
|
||||
structs.WriteRequest
|
||||
structs.DCSpecificRequest
|
||||
}
|
||||
|
||||
var readRequest struct {
|
||||
structs.QueryOptions
|
||||
structs.DCSpecificRequest
|
||||
}
|
||||
|
||||
// Server implements pbpeering.PeeringService to provide RPC operations for
|
||||
// managing peering relationships.
|
||||
type Server struct {
|
||||
|
@ -90,6 +106,12 @@ func (s *Server) Register(grpcServer *grpc.Server) {
|
|||
// providing access to CA data and the RPC system for forwarding requests to
|
||||
// other servers.
|
||||
type Backend interface {
|
||||
// ResolveTokenAndDefaultMeta returns an acl.Authorizer which authorizes
|
||||
// actions based on the permissions granted to the token.
|
||||
// If either entMeta or authzContext are non-nil they will be populated with the
|
||||
// partition and namespace from the token.
|
||||
ResolveTokenAndDefaultMeta(token string, entMeta *acl.EnterpriseMeta, authzCtx *acl.AuthorizerContext) (resolver.Result, error)
|
||||
|
||||
// GetAgentCACertificates returns the CA certificate to be returned in the peering token data
|
||||
GetAgentCACertificates() ([]string, error)
|
||||
|
||||
|
@ -165,11 +187,11 @@ func (s *Server) GenerateToken(
|
|||
return nil, fmt.Errorf("meta tags failed validation: %w", err)
|
||||
}
|
||||
|
||||
// TODO(peering): add metrics
|
||||
// TODO(peering): add tracing
|
||||
defer metrics.MeasureSince([]string{"peering", "generate_token"}, time.Now())
|
||||
|
||||
resp := &pbpeering.GenerateTokenResponse{}
|
||||
handled, err := s.ForwardRPC(req, func(conn *grpc.ClientConn) error {
|
||||
handled, err := s.ForwardRPC(&writeRequest, func(conn *grpc.ClientConn) error {
|
||||
ctx := external.ForwardMetadataContext(ctx)
|
||||
var err error
|
||||
resp, err = pbpeering.NewPeeringServiceClient(conn).GenerateToken(ctx, req)
|
||||
return err
|
||||
|
@ -178,6 +200,17 @@ func (s *Server) GenerateToken(
|
|||
return resp, err
|
||||
}
|
||||
|
||||
var authzCtx acl.AuthorizerContext
|
||||
entMeta := structs.DefaultEnterpriseMetaInPartition(req.Partition)
|
||||
authz, err := s.Backend.ResolveTokenAndDefaultMeta(external.TokenFromContext(ctx), entMeta, &authzCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := authz.ToAllowAuthorizer().PeeringWriteAllowed(&authzCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ca, err := s.Backend.GetAgentCACertificates()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -194,7 +227,7 @@ func (s *Server) GenerateToken(
|
|||
}
|
||||
}
|
||||
|
||||
peeringOrNil, err := s.getExistingPeering(req.PeerName, req.Partition)
|
||||
peeringOrNil, err := s.getExistingPeering(req.PeerName, entMeta.PartitionOrDefault())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -206,7 +239,7 @@ func (s *Server) GenerateToken(
|
|||
|
||||
canRetry := true
|
||||
RETRY_ONCE:
|
||||
id, err := s.getExistingOrCreateNewPeerID(req.PeerName, req.Partition)
|
||||
id, err := s.getExistingOrCreateNewPeerID(req.PeerName, entMeta.PartitionOrDefault())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -214,9 +247,10 @@ RETRY_ONCE:
|
|||
Peering: &pbpeering.Peering{
|
||||
ID: id,
|
||||
Name: req.PeerName,
|
||||
// TODO(peering): Normalize from ACL token once this endpoint is guarded by ACLs.
|
||||
Partition: req.PartitionOrDefault(),
|
||||
Meta: req.Meta,
|
||||
|
||||
// PartitionOrEmpty is used to avoid writing "default" in OSS.
|
||||
Partition: entMeta.PartitionOrEmpty(),
|
||||
},
|
||||
}
|
||||
if err := s.Backend.PeeringWrite(&writeReq); err != nil {
|
||||
|
@ -234,7 +268,7 @@ RETRY_ONCE:
|
|||
|
||||
q := state.Query{
|
||||
Value: strings.ToLower(req.PeerName),
|
||||
EnterpriseMeta: *structs.NodeEnterpriseMetaInPartition(req.Partition),
|
||||
EnterpriseMeta: *entMeta,
|
||||
}
|
||||
_, peering, err := s.Backend.Store().PeeringRead(nil, q)
|
||||
if err != nil {
|
||||
|
@ -288,7 +322,8 @@ func (s *Server) Establish(
|
|||
}
|
||||
|
||||
resp := &pbpeering.EstablishResponse{}
|
||||
handled, err := s.ForwardRPC(req, func(conn *grpc.ClientConn) error {
|
||||
handled, err := s.ForwardRPC(&writeRequest, func(conn *grpc.ClientConn) error {
|
||||
ctx := external.ForwardMetadataContext(ctx)
|
||||
var err error
|
||||
resp, err = pbpeering.NewPeeringServiceClient(conn).Establish(ctx, req)
|
||||
return err
|
||||
|
@ -299,7 +334,18 @@ func (s *Server) Establish(
|
|||
|
||||
defer metrics.MeasureSince([]string{"peering", "establish"}, time.Now())
|
||||
|
||||
peeringOrNil, err := s.getExistingPeering(req.PeerName, req.Partition)
|
||||
var authzCtx acl.AuthorizerContext
|
||||
entMeta := structs.DefaultEnterpriseMetaInPartition(req.Partition)
|
||||
authz, err := s.Backend.ResolveTokenAndDefaultMeta(external.TokenFromContext(ctx), entMeta, &authzCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := authz.ToAllowAuthorizer().PeeringWriteAllowed(&authzCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peeringOrNil, err := s.getExistingPeering(req.PeerName, entMeta.PartitionOrDefault())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -341,6 +387,9 @@ func (s *Server) Establish(
|
|||
PeerID: tok.PeerID,
|
||||
Meta: req.Meta,
|
||||
State: pbpeering.PeeringState_ESTABLISHING,
|
||||
|
||||
// PartitionOrEmpty is used to avoid writing "default" in OSS.
|
||||
Partition: entMeta.PartitionOrEmpty(),
|
||||
},
|
||||
}
|
||||
if err = s.Backend.PeeringWrite(writeReq); err != nil {
|
||||
|
@ -350,6 +399,7 @@ func (s *Server) Establish(
|
|||
return resp, nil
|
||||
}
|
||||
|
||||
// OPTIMIZE: Handle blocking queries
|
||||
func (s *Server) PeeringRead(ctx context.Context, req *pbpeering.PeeringReadRequest) (*pbpeering.PeeringReadResponse, error) {
|
||||
if !s.Config.PeeringEnabled {
|
||||
return nil, peeringNotEnabledErr
|
||||
|
@ -360,7 +410,8 @@ func (s *Server) PeeringRead(ctx context.Context, req *pbpeering.PeeringReadRequ
|
|||
}
|
||||
|
||||
var resp *pbpeering.PeeringReadResponse
|
||||
handled, err := s.ForwardRPC(req, func(conn *grpc.ClientConn) error {
|
||||
handled, err := s.ForwardRPC(&readRequest, func(conn *grpc.ClientConn) error {
|
||||
ctx := external.ForwardMetadataContext(ctx)
|
||||
var err error
|
||||
resp, err = pbpeering.NewPeeringServiceClient(conn).PeeringRead(ctx, req)
|
||||
return err
|
||||
|
@ -370,12 +421,22 @@ func (s *Server) PeeringRead(ctx context.Context, req *pbpeering.PeeringReadRequ
|
|||
}
|
||||
|
||||
defer metrics.MeasureSince([]string{"peering", "read"}, time.Now())
|
||||
// TODO(peering): ACL check request token
|
||||
|
||||
// TODO(peering): handle blocking queries
|
||||
var authzCtx acl.AuthorizerContext
|
||||
entMeta := structs.DefaultEnterpriseMetaInPartition(req.Partition)
|
||||
authz, err := s.Backend.ResolveTokenAndDefaultMeta(external.TokenFromContext(ctx), entMeta, &authzCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := authz.ToAllowAuthorizer().PeeringReadAllowed(&authzCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
q := state.Query{
|
||||
Value: strings.ToLower(req.Name),
|
||||
EnterpriseMeta: *structs.NodeEnterpriseMetaInPartition(req.Partition)}
|
||||
EnterpriseMeta: *entMeta,
|
||||
}
|
||||
_, peering, err := s.Backend.Store().PeeringRead(nil, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -388,6 +449,7 @@ func (s *Server) PeeringRead(ctx context.Context, req *pbpeering.PeeringReadRequ
|
|||
return &pbpeering.PeeringReadResponse{Peering: cp}, nil
|
||||
}
|
||||
|
||||
// OPTIMIZE: Handle blocking queries
|
||||
func (s *Server) PeeringList(ctx context.Context, req *pbpeering.PeeringListRequest) (*pbpeering.PeeringListResponse, error) {
|
||||
if !s.Config.PeeringEnabled {
|
||||
return nil, peeringNotEnabledErr
|
||||
|
@ -398,7 +460,8 @@ func (s *Server) PeeringList(ctx context.Context, req *pbpeering.PeeringListRequ
|
|||
}
|
||||
|
||||
var resp *pbpeering.PeeringListResponse
|
||||
handled, err := s.ForwardRPC(req, func(conn *grpc.ClientConn) error {
|
||||
handled, err := s.ForwardRPC(&readRequest, func(conn *grpc.ClientConn) error {
|
||||
ctx := external.ForwardMetadataContext(ctx)
|
||||
var err error
|
||||
resp, err = pbpeering.NewPeeringServiceClient(conn).PeeringList(ctx, req)
|
||||
return err
|
||||
|
@ -407,11 +470,20 @@ func (s *Server) PeeringList(ctx context.Context, req *pbpeering.PeeringListRequ
|
|||
return resp, err
|
||||
}
|
||||
|
||||
defer metrics.MeasureSince([]string{"peering", "list"}, time.Now())
|
||||
// TODO(peering): ACL check request token
|
||||
var authzCtx acl.AuthorizerContext
|
||||
entMeta := structs.DefaultEnterpriseMetaInPartition(req.Partition)
|
||||
authz, err := s.Backend.ResolveTokenAndDefaultMeta(external.TokenFromContext(ctx), entMeta, &authzCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO(peering): handle blocking queries
|
||||
_, peerings, err := s.Backend.Store().PeeringList(nil, *structs.NodeEnterpriseMetaInPartition(req.Partition))
|
||||
if err := authz.ToAllowAuthorizer().PeeringReadAllowed(&authzCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer metrics.MeasureSince([]string{"peering", "list"}, time.Now())
|
||||
|
||||
_, peerings, err := s.Backend.Store().PeeringList(nil, *entMeta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -465,7 +537,8 @@ func (s *Server) PeeringWrite(ctx context.Context, req *pbpeering.PeeringWriteRe
|
|||
}
|
||||
|
||||
var resp *pbpeering.PeeringWriteResponse
|
||||
handled, err := s.ForwardRPC(req, func(conn *grpc.ClientConn) error {
|
||||
handled, err := s.ForwardRPC(&writeRequest, func(conn *grpc.ClientConn) error {
|
||||
ctx := external.ForwardMetadataContext(ctx)
|
||||
var err error
|
||||
resp, err = pbpeering.NewPeeringServiceClient(conn).PeeringWrite(ctx, req)
|
||||
return err
|
||||
|
@ -475,19 +548,28 @@ func (s *Server) PeeringWrite(ctx context.Context, req *pbpeering.PeeringWriteRe
|
|||
}
|
||||
|
||||
defer metrics.MeasureSince([]string{"peering", "write"}, time.Now())
|
||||
// TODO(peering): ACL check request token
|
||||
|
||||
var authzCtx acl.AuthorizerContext
|
||||
entMeta := structs.DefaultEnterpriseMetaInPartition(req.Peering.Partition)
|
||||
authz, err := s.Backend.ResolveTokenAndDefaultMeta(external.TokenFromContext(ctx), entMeta, &authzCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := authz.ToAllowAuthorizer().PeeringWriteAllowed(&authzCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.Peering == nil {
|
||||
return nil, fmt.Errorf("missing required peering body")
|
||||
}
|
||||
|
||||
id, err := s.getExistingOrCreateNewPeerID(req.Peering.Name, req.Peering.Partition)
|
||||
id, err := s.getExistingOrCreateNewPeerID(req.Peering.Name, entMeta.PartitionOrDefault())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Peering.ID = id
|
||||
|
||||
// TODO(peering): handle blocking queries
|
||||
err = s.Backend.PeeringWrite(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -505,7 +587,8 @@ func (s *Server) PeeringDelete(ctx context.Context, req *pbpeering.PeeringDelete
|
|||
}
|
||||
|
||||
var resp *pbpeering.PeeringDeleteResponse
|
||||
handled, err := s.ForwardRPC(req, func(conn *grpc.ClientConn) error {
|
||||
handled, err := s.ForwardRPC(&writeRequest, func(conn *grpc.ClientConn) error {
|
||||
ctx := external.ForwardMetadataContext(ctx)
|
||||
var err error
|
||||
resp, err = pbpeering.NewPeeringServiceClient(conn).PeeringDelete(ctx, req)
|
||||
return err
|
||||
|
@ -515,13 +598,21 @@ func (s *Server) PeeringDelete(ctx context.Context, req *pbpeering.PeeringDelete
|
|||
}
|
||||
|
||||
defer metrics.MeasureSince([]string{"peering", "delete"}, time.Now())
|
||||
// TODO(peering): ACL check request token
|
||||
|
||||
// TODO(peering): handle blocking queries
|
||||
var authzCtx acl.AuthorizerContext
|
||||
entMeta := structs.DefaultEnterpriseMetaInPartition(req.Partition)
|
||||
authz, err := s.Backend.ResolveTokenAndDefaultMeta(external.TokenFromContext(ctx), entMeta, &authzCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := authz.ToAllowAuthorizer().PeeringWriteAllowed(&authzCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
q := state.Query{
|
||||
Value: strings.ToLower(req.Name),
|
||||
EnterpriseMeta: *structs.NodeEnterpriseMetaInPartition(req.Partition),
|
||||
EnterpriseMeta: *entMeta,
|
||||
}
|
||||
_, existing, err := s.Backend.Store().PeeringRead(nil, q)
|
||||
if err != nil {
|
||||
|
@ -543,9 +634,11 @@ func (s *Server) PeeringDelete(ctx context.Context, req *pbpeering.PeeringDelete
|
|||
// for deletion the peering is effectively gone.
|
||||
ID: existing.ID,
|
||||
Name: req.Name,
|
||||
Partition: req.Partition,
|
||||
State: pbpeering.PeeringState_DELETING,
|
||||
DeletedAt: structs.TimeToProto(time.Now().UTC()),
|
||||
|
||||
// PartitionOrEmpty is used to avoid writing "default" in OSS.
|
||||
Partition: entMeta.PartitionOrEmpty(),
|
||||
},
|
||||
}
|
||||
err = s.Backend.PeeringWrite(writeReq)
|
||||
|
@ -555,6 +648,7 @@ func (s *Server) PeeringDelete(ctx context.Context, req *pbpeering.PeeringDelete
|
|||
return &pbpeering.PeeringDeleteResponse{}, nil
|
||||
}
|
||||
|
||||
// OPTIMIZE: Handle blocking queries
|
||||
func (s *Server) TrustBundleRead(ctx context.Context, req *pbpeering.TrustBundleReadRequest) (*pbpeering.TrustBundleReadResponse, error) {
|
||||
if !s.Config.PeeringEnabled {
|
||||
return nil, peeringNotEnabledErr
|
||||
|
@ -565,7 +659,8 @@ func (s *Server) TrustBundleRead(ctx context.Context, req *pbpeering.TrustBundle
|
|||
}
|
||||
|
||||
var resp *pbpeering.TrustBundleReadResponse
|
||||
handled, err := s.ForwardRPC(req, func(conn *grpc.ClientConn) error {
|
||||
handled, err := s.ForwardRPC(&readRequest, func(conn *grpc.ClientConn) error {
|
||||
ctx := external.ForwardMetadataContext(ctx)
|
||||
var err error
|
||||
resp, err = pbpeering.NewPeeringServiceClient(conn).TrustBundleRead(ctx, req)
|
||||
return err
|
||||
|
@ -575,13 +670,21 @@ func (s *Server) TrustBundleRead(ctx context.Context, req *pbpeering.TrustBundle
|
|||
}
|
||||
|
||||
defer metrics.MeasureSince([]string{"peering", "trust_bundle_read"}, time.Now())
|
||||
// TODO(peering): ACL check request token
|
||||
|
||||
// TODO(peering): handle blocking queries
|
||||
var authzCtx acl.AuthorizerContext
|
||||
entMeta := structs.DefaultEnterpriseMetaInPartition(req.Partition)
|
||||
authz, err := s.Backend.ResolveTokenAndDefaultMeta(external.TokenFromContext(ctx), entMeta, &authzCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := authz.ToAllowAuthorizer().ServiceWriteAnyAllowed(&authzCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
idx, trustBundle, err := s.Backend.Store().PeeringTrustBundleRead(nil, state.Query{
|
||||
Value: req.Name,
|
||||
EnterpriseMeta: *structs.NodeEnterpriseMetaInPartition(req.Partition),
|
||||
EnterpriseMeta: *entMeta,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read trust bundle for peer %s: %w", req.Name, err)
|
||||
|
@ -594,6 +697,7 @@ func (s *Server) TrustBundleRead(ctx context.Context, req *pbpeering.TrustBundle
|
|||
}
|
||||
|
||||
// TODO(peering): rename rpc & request/response to drop the "service" part
|
||||
// OPTIMIZE: Handle blocking queries
|
||||
func (s *Server) TrustBundleListByService(ctx context.Context, req *pbpeering.TrustBundleListByServiceRequest) (*pbpeering.TrustBundleListByServiceResponse, error) {
|
||||
if !s.Config.PeeringEnabled {
|
||||
return nil, peeringNotEnabledErr
|
||||
|
@ -605,9 +709,13 @@ func (s *Server) TrustBundleListByService(ctx context.Context, req *pbpeering.Tr
|
|||
if err := s.Backend.EnterpriseCheckNamespaces(req.Namespace); err != nil {
|
||||
return nil, grpcstatus.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
if req.ServiceName == "" {
|
||||
return nil, errors.New("missing service name")
|
||||
}
|
||||
|
||||
var resp *pbpeering.TrustBundleListByServiceResponse
|
||||
handled, err := s.ForwardRPC(req, func(conn *grpc.ClientConn) error {
|
||||
handled, err := s.ForwardRPC(&readRequest, func(conn *grpc.ClientConn) error {
|
||||
ctx := external.ForwardMetadataContext(ctx)
|
||||
var err error
|
||||
resp, err = pbpeering.NewPeeringServiceClient(conn).TrustBundleListByService(ctx, req)
|
||||
return err
|
||||
|
@ -617,11 +725,17 @@ func (s *Server) TrustBundleListByService(ctx context.Context, req *pbpeering.Tr
|
|||
}
|
||||
|
||||
defer metrics.MeasureSince([]string{"peering", "trust_bundle_list_by_service"}, time.Now())
|
||||
// TODO(peering): ACL check request token for service:write on the service name
|
||||
|
||||
// TODO(peering): handle blocking queries
|
||||
|
||||
var authzCtx acl.AuthorizerContext
|
||||
entMeta := acl.NewEnterpriseMetaWithPartition(req.Partition, req.Namespace)
|
||||
authz, err := s.Backend.ResolveTokenAndDefaultMeta(external.TokenFromContext(ctx), &entMeta, &authzCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := authz.ToAllowAuthorizer().ServiceWriteAllowed(req.ServiceName, &authzCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
idx uint64
|
||||
|
@ -629,10 +743,10 @@ func (s *Server) TrustBundleListByService(ctx context.Context, req *pbpeering.Tr
|
|||
)
|
||||
|
||||
switch {
|
||||
case req.ServiceName != "":
|
||||
idx, bundles, err = s.Backend.Store().TrustBundleListByService(nil, req.ServiceName, s.Datacenter, entMeta)
|
||||
case req.Kind == string(structs.ServiceKindMeshGateway):
|
||||
idx, bundles, err = s.Backend.Store().PeeringTrustBundleList(nil, entMeta)
|
||||
case req.ServiceName != "":
|
||||
idx, bundles, err = s.Backend.Store().TrustBundleListByService(nil, req.ServiceName, s.Datacenter, entMeta)
|
||||
case req.Kind != "":
|
||||
return nil, grpcstatus.Error(codes.InvalidArgument, "kind must be mesh-gateway if set")
|
||||
default:
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/hashicorp/consul/agent/consul"
|
||||
"github.com/hashicorp/consul/agent/consul/state"
|
||||
"github.com/hashicorp/consul/agent/consul/stream"
|
||||
external "github.com/hashicorp/consul/agent/grpc-external"
|
||||
grpc "github.com/hashicorp/consul/agent/grpc-internal"
|
||||
"github.com/hashicorp/consul/agent/grpc-internal/resolver"
|
||||
"github.com/hashicorp/consul/agent/pool"
|
||||
|
@ -41,6 +42,13 @@ import (
|
|||
"github.com/hashicorp/consul/types"
|
||||
)
|
||||
|
||||
const (
|
||||
testTokenPeeringReadSecret = "9a83c138-a0c7-40f1-89fa-6acf9acd78f5"
|
||||
testTokenPeeringWriteSecret = "91f90a41-0840-4afe-b615-68745f9e16c1"
|
||||
testTokenServiceReadSecret = "1ef8e3cf-6e95-49aa-9f73-a0d3ad1a77d4"
|
||||
testTokenServiceWriteSecret = "4a3dc05d-d86c-4f20-be43-8f4f8f045fea"
|
||||
)
|
||||
|
||||
func generateTooManyMetaKeys() map[string]string {
|
||||
// todo -- modularize in structs.go or testing.go
|
||||
tooMuchMeta := make(map[string]string)
|
||||
|
@ -70,12 +78,12 @@ func TestPeeringService_GenerateToken(t *testing.T) {
|
|||
|
||||
// TODO(peering): for more failure cases, consider using a table test
|
||||
// check meta tags
|
||||
reqE := pbpeering.GenerateTokenRequest{PeerName: "peerB", Datacenter: "dc1", Meta: generateTooManyMetaKeys()}
|
||||
reqE := pbpeering.GenerateTokenRequest{PeerName: "peerB", Meta: generateTooManyMetaKeys()}
|
||||
_, errE := client.GenerateToken(ctx, &reqE)
|
||||
require.EqualError(t, errE, "rpc error: code = Unknown desc = meta tags failed validation: Node metadata cannot contain more than 64 key/value pairs")
|
||||
|
||||
// happy path
|
||||
req := pbpeering.GenerateTokenRequest{PeerName: "peerB", Datacenter: "dc1", Meta: map[string]string{"foo": "bar"}}
|
||||
req := pbpeering.GenerateTokenRequest{PeerName: "peerB", Meta: map[string]string{"foo": "bar"}}
|
||||
resp, err := client.GenerateToken(ctx, &req)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -129,7 +137,7 @@ func TestPeeringService_GenerateTokenExternalAddress(t *testing.T) {
|
|||
|
||||
externalAddress := "32.1.2.3:8502"
|
||||
// happy path
|
||||
req := pbpeering.GenerateTokenRequest{PeerName: "peerB", Datacenter: "dc1", Meta: map[string]string{"foo": "bar"}, ServerExternalAddresses: []string{externalAddress}}
|
||||
req := pbpeering.GenerateTokenRequest{PeerName: "peerB", Meta: map[string]string{"foo": "bar"}, ServerExternalAddresses: []string{externalAddress}}
|
||||
resp, err := client.GenerateToken(ctx, &req)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -144,6 +152,62 @@ func TestPeeringService_GenerateTokenExternalAddress(t *testing.T) {
|
|||
require.Equal(t, []string{ca}, token.CA)
|
||||
}
|
||||
|
||||
func TestPeeringService_GenerateToken_ACLEnforcement(t *testing.T) {
|
||||
// TODO(peering): see note on newTestServer, refactor to not use this
|
||||
s := newTestServer(t, func(conf *consul.Config) {
|
||||
conf.ACLsEnabled = true
|
||||
conf.ACLResolverSettings.ACLDefaultPolicy = acl.PolicyDeny
|
||||
})
|
||||
upsertTestACLs(t, s.Server.FSM().State())
|
||||
|
||||
client := pbpeering.NewPeeringServiceClient(s.ClientConn(t))
|
||||
|
||||
type testcase struct {
|
||||
name string
|
||||
req *pbpeering.GenerateTokenRequest
|
||||
token string
|
||||
expectErr string
|
||||
}
|
||||
run := func(t *testing.T, tc testcase) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
_, err := client.GenerateToken(external.ContextWithToken(ctx, tc.token), tc.req)
|
||||
if tc.expectErr != "" {
|
||||
require.Contains(t, err.Error(), tc.expectErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
}
|
||||
tcs := []testcase{
|
||||
{
|
||||
name: "anonymous token lacks permissions",
|
||||
req: &pbpeering.GenerateTokenRequest{PeerName: "foo"},
|
||||
expectErr: "lacks permission 'peering:write'",
|
||||
},
|
||||
{
|
||||
name: "read token lacks permissions",
|
||||
req: &pbpeering.GenerateTokenRequest{
|
||||
PeerName: "foo",
|
||||
},
|
||||
token: testTokenPeeringReadSecret,
|
||||
expectErr: "lacks permission 'peering:write'",
|
||||
},
|
||||
{
|
||||
name: "write token grants permission",
|
||||
req: &pbpeering.GenerateTokenRequest{
|
||||
PeerName: "foo",
|
||||
},
|
||||
token: testTokenPeeringWriteSecret,
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
run(t, tc)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPeeringService_Establish(t *testing.T) {
|
||||
validToken := peering.TestPeeringToken("83474a06-cca4-4ff4-99a4-4152929c8160")
|
||||
validTokenJSON, _ := json.Marshal(&validToken)
|
||||
|
@ -250,6 +314,71 @@ func TestPeeringService_Establish(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPeeringService_Establish_ACLEnforcement(t *testing.T) {
|
||||
validToken := peering.TestPeeringToken("83474a06-cca4-4ff4-99a4-4152929c8160")
|
||||
validTokenJSON, _ := json.Marshal(&validToken)
|
||||
validTokenB64 := base64.StdEncoding.EncodeToString(validTokenJSON)
|
||||
|
||||
// TODO(peering): see note on newTestServer, refactor to not use this
|
||||
s := newTestServer(t, func(conf *consul.Config) {
|
||||
conf.ACLsEnabled = true
|
||||
conf.ACLResolverSettings.ACLDefaultPolicy = acl.PolicyDeny
|
||||
})
|
||||
upsertTestACLs(t, s.Server.FSM().State())
|
||||
|
||||
client := pbpeering.NewPeeringServiceClient(s.ClientConn(t))
|
||||
|
||||
type testcase struct {
|
||||
name string
|
||||
req *pbpeering.EstablishRequest
|
||||
token string
|
||||
expectErr string
|
||||
}
|
||||
run := func(t *testing.T, tc testcase) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
_, err := client.Establish(external.ContextWithToken(ctx, tc.token), tc.req)
|
||||
if tc.expectErr != "" {
|
||||
require.Contains(t, err.Error(), tc.expectErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
}
|
||||
tcs := []testcase{
|
||||
{
|
||||
name: "anonymous token lacks permissions",
|
||||
req: &pbpeering.EstablishRequest{
|
||||
PeerName: "foo",
|
||||
PeeringToken: validTokenB64,
|
||||
},
|
||||
expectErr: "lacks permission 'peering:write'",
|
||||
},
|
||||
{
|
||||
name: "read token lacks permissions",
|
||||
req: &pbpeering.EstablishRequest{
|
||||
PeerName: "foo",
|
||||
PeeringToken: validTokenB64,
|
||||
},
|
||||
token: testTokenPeeringReadSecret,
|
||||
expectErr: "lacks permission 'peering:write'",
|
||||
},
|
||||
{
|
||||
name: "write token grants permission",
|
||||
req: &pbpeering.EstablishRequest{
|
||||
PeerName: "foo",
|
||||
PeeringToken: validTokenB64,
|
||||
},
|
||||
token: testTokenPeeringWriteSecret,
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
run(t, tc)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPeeringService_Read(t *testing.T) {
|
||||
// TODO(peering): see note on newTestServer, refactor to not use this
|
||||
s := newTestServer(t, nil)
|
||||
|
@ -309,6 +438,72 @@ func TestPeeringService_Read(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPeeringService_Read_ACLEnforcement(t *testing.T) {
|
||||
// TODO(peering): see note on newTestServer, refactor to not use this
|
||||
s := newTestServer(t, func(conf *consul.Config) {
|
||||
conf.ACLsEnabled = true
|
||||
conf.ACLResolverSettings.ACLDefaultPolicy = acl.PolicyDeny
|
||||
})
|
||||
upsertTestACLs(t, s.Server.FSM().State())
|
||||
|
||||
// insert peering directly to state store
|
||||
p := &pbpeering.Peering{
|
||||
ID: testUUID(t),
|
||||
Name: "foo",
|
||||
State: pbpeering.PeeringState_ESTABLISHING,
|
||||
PeerCAPems: nil,
|
||||
PeerServerName: "test",
|
||||
PeerServerAddresses: []string{"addr1"},
|
||||
ImportedServiceCount: 0,
|
||||
ExportedServiceCount: 0,
|
||||
}
|
||||
err := s.Server.FSM().State().PeeringWrite(10, p)
|
||||
require.NoError(t, err)
|
||||
|
||||
client := pbpeering.NewPeeringServiceClient(s.ClientConn(t))
|
||||
|
||||
type testcase struct {
|
||||
name string
|
||||
req *pbpeering.PeeringReadRequest
|
||||
expect *pbpeering.PeeringReadResponse
|
||||
token string
|
||||
expectErr string
|
||||
}
|
||||
run := func(t *testing.T, tc testcase) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
resp, err := client.PeeringRead(external.ContextWithToken(ctx, tc.token), tc.req)
|
||||
if tc.expectErr != "" {
|
||||
require.Contains(t, err.Error(), tc.expectErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
prototest.AssertDeepEqual(t, tc.expect, resp)
|
||||
}
|
||||
tcs := []testcase{
|
||||
{
|
||||
name: "anonymous token lacks permissions",
|
||||
req: &pbpeering.PeeringReadRequest{Name: "foo"},
|
||||
expect: &pbpeering.PeeringReadResponse{Peering: p},
|
||||
expectErr: "lacks permission 'peering:read'",
|
||||
},
|
||||
{
|
||||
name: "read token grants permission",
|
||||
req: &pbpeering.PeeringReadRequest{
|
||||
Name: "foo",
|
||||
},
|
||||
expect: &pbpeering.PeeringReadResponse{Peering: p},
|
||||
token: testTokenPeeringReadSecret,
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
run(t, tc)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPeeringService_Delete(t *testing.T) {
|
||||
// TODO(peering): see note on newTestServer, refactor to not use this
|
||||
s := newTestServer(t, nil)
|
||||
|
@ -344,6 +539,76 @@ func TestPeeringService_Delete(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestPeeringService_Delete_ACLEnforcement(t *testing.T) {
|
||||
// TODO(peering): see note on newTestServer, refactor to not use this
|
||||
s := newTestServer(t, func(conf *consul.Config) {
|
||||
conf.ACLsEnabled = true
|
||||
conf.ACLResolverSettings.ACLDefaultPolicy = acl.PolicyDeny
|
||||
})
|
||||
upsertTestACLs(t, s.Server.FSM().State())
|
||||
|
||||
p := &pbpeering.Peering{
|
||||
ID: testUUID(t),
|
||||
Name: "foo",
|
||||
State: pbpeering.PeeringState_ESTABLISHING,
|
||||
PeerCAPems: nil,
|
||||
PeerServerName: "test",
|
||||
PeerServerAddresses: []string{"addr1"},
|
||||
}
|
||||
err := s.Server.FSM().State().PeeringWrite(10, p)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, p.DeletedAt)
|
||||
require.True(t, p.IsActive())
|
||||
|
||||
client := pbpeering.NewPeeringServiceClient(s.ClientConn(t))
|
||||
|
||||
type testcase struct {
|
||||
name string
|
||||
req *pbpeering.PeeringDeleteRequest
|
||||
token string
|
||||
expectErr string
|
||||
}
|
||||
run := func(t *testing.T, tc testcase) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
_, err = client.PeeringDelete(external.ContextWithToken(ctx, tc.token), tc.req)
|
||||
if tc.expectErr != "" {
|
||||
require.Contains(t, err.Error(), tc.expectErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
}
|
||||
tcs := []testcase{
|
||||
{
|
||||
name: "anonymous token lacks permissions",
|
||||
req: &pbpeering.PeeringDeleteRequest{Name: "foo"},
|
||||
expectErr: "lacks permission 'peering:write'",
|
||||
},
|
||||
{
|
||||
name: "read token lacks permissions",
|
||||
req: &pbpeering.PeeringDeleteRequest{
|
||||
Name: "foo",
|
||||
},
|
||||
token: testTokenPeeringReadSecret,
|
||||
expectErr: "lacks permission 'peering:write'",
|
||||
},
|
||||
{
|
||||
name: "write token grants permission",
|
||||
req: &pbpeering.PeeringDeleteRequest{
|
||||
Name: "foo",
|
||||
},
|
||||
token: testTokenPeeringWriteSecret,
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
run(t, tc)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestPeeringService_List(t *testing.T) {
|
||||
// TODO(peering): see note on newTestServer, refactor to not use this
|
||||
s := newTestServer(t, nil)
|
||||
|
@ -388,6 +653,78 @@ func TestPeeringService_List(t *testing.T) {
|
|||
prototest.AssertDeepEqual(t, expect, resp)
|
||||
}
|
||||
|
||||
func TestPeeringService_List_ACLEnforcement(t *testing.T) {
|
||||
// TODO(peering): see note on newTestServer, refactor to not use this
|
||||
s := newTestServer(t, func(conf *consul.Config) {
|
||||
conf.ACLsEnabled = true
|
||||
conf.ACLResolverSettings.ACLDefaultPolicy = acl.PolicyDeny
|
||||
})
|
||||
upsertTestACLs(t, s.Server.FSM().State())
|
||||
|
||||
// insert peering directly to state store
|
||||
foo := &pbpeering.Peering{
|
||||
ID: testUUID(t),
|
||||
Name: "foo",
|
||||
State: pbpeering.PeeringState_ESTABLISHING,
|
||||
PeerCAPems: nil,
|
||||
PeerServerName: "fooservername",
|
||||
PeerServerAddresses: []string{"addr1"},
|
||||
ImportedServiceCount: 0,
|
||||
ExportedServiceCount: 0,
|
||||
}
|
||||
require.NoError(t, s.Server.FSM().State().PeeringWrite(10, foo))
|
||||
bar := &pbpeering.Peering{
|
||||
ID: testUUID(t),
|
||||
Name: "bar",
|
||||
State: pbpeering.PeeringState_ACTIVE,
|
||||
PeerCAPems: nil,
|
||||
PeerServerName: "barservername",
|
||||
PeerServerAddresses: []string{"addr1"},
|
||||
ImportedServiceCount: 0,
|
||||
ExportedServiceCount: 0,
|
||||
}
|
||||
require.NoError(t, s.Server.FSM().State().PeeringWrite(15, bar))
|
||||
|
||||
client := pbpeering.NewPeeringServiceClient(s.ClientConn(t))
|
||||
|
||||
type testcase struct {
|
||||
name string
|
||||
token string
|
||||
expect *pbpeering.PeeringListResponse
|
||||
expectErr string
|
||||
}
|
||||
run := func(t *testing.T, tc testcase) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
resp, err := client.PeeringList(external.ContextWithToken(ctx, tc.token), &pbpeering.PeeringListRequest{})
|
||||
if tc.expectErr != "" {
|
||||
require.Contains(t, err.Error(), tc.expectErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
prototest.AssertDeepEqual(t, tc.expect, resp)
|
||||
}
|
||||
tcs := []testcase{
|
||||
{
|
||||
name: "anonymous token lacks permissions",
|
||||
expectErr: "lacks permission 'peering:read'",
|
||||
},
|
||||
{
|
||||
name: "read token grants permission",
|
||||
token: testTokenPeeringReadSecret,
|
||||
expect: &pbpeering.PeeringListResponse{
|
||||
Peerings: []*pbpeering.Peering{bar, foo},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
run(t, tc)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPeeringService_TrustBundleRead(t *testing.T) {
|
||||
srv := newTestServer(t, nil)
|
||||
store := srv.Server.FSM().State()
|
||||
|
@ -396,25 +733,6 @@ func TestPeeringService_TrustBundleRead(t *testing.T) {
|
|||
var lastIdx uint64 = 1
|
||||
_ = setupTestPeering(t, store, "my-peering", lastIdx)
|
||||
|
||||
mysql := &structs.CheckServiceNode{
|
||||
Node: &structs.Node{
|
||||
Node: "node1",
|
||||
Address: "10.0.0.1",
|
||||
PeerName: "my-peering",
|
||||
},
|
||||
Service: &structs.NodeService{
|
||||
ID: "mysql-1",
|
||||
Service: "mysql",
|
||||
Port: 5000,
|
||||
PeerName: "my-peering",
|
||||
},
|
||||
}
|
||||
|
||||
lastIdx++
|
||||
require.NoError(t, store.EnsureNode(lastIdx, mysql.Node))
|
||||
lastIdx++
|
||||
require.NoError(t, store.EnsureService(lastIdx, mysql.Node.Node, mysql.Service))
|
||||
|
||||
bundle := &pbpeering.PeeringTrustBundle{
|
||||
TrustDomain: "peer1.com",
|
||||
PeerName: "my-peering",
|
||||
|
@ -435,6 +753,76 @@ func TestPeeringService_TrustBundleRead(t *testing.T) {
|
|||
prototest.AssertDeepEqual(t, bundle, resp.Bundle)
|
||||
}
|
||||
|
||||
func TestPeeringService_TrustBundleRead_ACLEnforcement(t *testing.T) {
|
||||
// TODO(peering): see note on newTestServer, refactor to not use this
|
||||
s := newTestServer(t, func(conf *consul.Config) {
|
||||
conf.ACLsEnabled = true
|
||||
conf.ACLResolverSettings.ACLDefaultPolicy = acl.PolicyDeny
|
||||
})
|
||||
store := s.Server.FSM().State()
|
||||
upsertTestACLs(t, s.Server.FSM().State())
|
||||
|
||||
// Insert peering and trust bundle directly to state store.
|
||||
_ = setupTestPeering(t, store, "my-peering", 10)
|
||||
|
||||
bundle := &pbpeering.PeeringTrustBundle{
|
||||
TrustDomain: "peer1.com",
|
||||
PeerName: "my-peering",
|
||||
RootPEMs: []string{"peer1-root-1"},
|
||||
}
|
||||
require.NoError(t, store.PeeringTrustBundleWrite(11, bundle))
|
||||
|
||||
client := pbpeering.NewPeeringServiceClient(s.ClientConn(t))
|
||||
|
||||
type testcase struct {
|
||||
name string
|
||||
req *pbpeering.TrustBundleReadRequest
|
||||
token string
|
||||
expect *pbpeering.PeeringTrustBundle
|
||||
expectErr string
|
||||
}
|
||||
run := func(t *testing.T, tc testcase) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
resp, err := client.TrustBundleRead(external.ContextWithToken(ctx, tc.token), tc.req)
|
||||
if tc.expectErr != "" {
|
||||
require.Contains(t, err.Error(), tc.expectErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
prototest.AssertDeepEqual(t, tc.expect, resp.Bundle)
|
||||
}
|
||||
tcs := []testcase{
|
||||
{
|
||||
name: "anonymous token lacks permissions",
|
||||
req: &pbpeering.TrustBundleReadRequest{Name: "foo"},
|
||||
expectErr: "lacks permission 'service:write'",
|
||||
},
|
||||
{
|
||||
name: "service read token lacks permissions",
|
||||
req: &pbpeering.TrustBundleReadRequest{
|
||||
Name: "my-peering",
|
||||
},
|
||||
token: testTokenServiceReadSecret,
|
||||
expectErr: "lacks permission 'service:write'",
|
||||
},
|
||||
{
|
||||
name: "with service write token",
|
||||
req: &pbpeering.TrustBundleReadRequest{
|
||||
Name: "my-peering",
|
||||
},
|
||||
token: testTokenServiceWriteSecret,
|
||||
expect: bundle,
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
run(t, tc)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Setup:
|
||||
// - Peerings "foo" and "bar" with trust bundles saved
|
||||
// - "api" service exported to both "foo" and "bar"
|
||||
|
@ -667,6 +1055,116 @@ func TestPeeringService_PeeringDisabled(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestPeeringService_TrustBundleListByService_ACLEnforcement(t *testing.T) {
|
||||
// TODO(peering): see note on newTestServer, refactor to not use this
|
||||
s := newTestServer(t, func(conf *consul.Config) {
|
||||
conf.ACLsEnabled = true
|
||||
conf.ACLResolverSettings.ACLDefaultPolicy = acl.PolicyDeny
|
||||
})
|
||||
store := s.Server.FSM().State()
|
||||
upsertTestACLs(t, s.Server.FSM().State())
|
||||
|
||||
var lastIdx uint64 = 10
|
||||
|
||||
lastIdx++
|
||||
require.NoError(t, s.Server.FSM().State().PeeringWrite(lastIdx, &pbpeering.Peering{
|
||||
ID: testUUID(t),
|
||||
Name: "foo",
|
||||
State: pbpeering.PeeringState_ESTABLISHING,
|
||||
PeerServerName: "test",
|
||||
PeerServerAddresses: []string{"addr1"},
|
||||
}))
|
||||
|
||||
lastIdx++
|
||||
require.NoError(t, store.PeeringTrustBundleWrite(lastIdx, &pbpeering.PeeringTrustBundle{
|
||||
TrustDomain: "foo.com",
|
||||
PeerName: "foo",
|
||||
RootPEMs: []string{"foo-root-1"},
|
||||
}))
|
||||
|
||||
lastIdx++
|
||||
require.NoError(t, store.EnsureNode(lastIdx, &structs.Node{
|
||||
Node: "my-node", Address: "127.0.0.1",
|
||||
}))
|
||||
|
||||
lastIdx++
|
||||
require.NoError(t, store.EnsureService(lastIdx, "my-node", &structs.NodeService{
|
||||
ID: "api",
|
||||
Service: "api",
|
||||
Port: 8000,
|
||||
}))
|
||||
|
||||
entry := structs.ExportedServicesConfigEntry{
|
||||
Name: "default",
|
||||
Services: []structs.ExportedService{
|
||||
{
|
||||
Name: "api",
|
||||
Consumers: []structs.ServiceConsumer{
|
||||
{
|
||||
PeerName: "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
require.NoError(t, entry.Normalize())
|
||||
require.NoError(t, entry.Validate())
|
||||
|
||||
lastIdx++
|
||||
require.NoError(t, store.EnsureConfigEntry(lastIdx, &entry))
|
||||
|
||||
client := pbpeering.NewPeeringServiceClient(s.ClientConn(t))
|
||||
|
||||
type testcase struct {
|
||||
name string
|
||||
req *pbpeering.TrustBundleListByServiceRequest
|
||||
token string
|
||||
expect []string
|
||||
expectErr string
|
||||
}
|
||||
run := func(t *testing.T, tc testcase) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
resp, err := client.TrustBundleListByService(external.ContextWithToken(ctx, tc.token), tc.req)
|
||||
if tc.expectErr != "" {
|
||||
require.Contains(t, err.Error(), tc.expectErr)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
require.Len(t, resp.Bundles, 1)
|
||||
require.Equal(t, tc.expect, resp.Bundles[0].RootPEMs)
|
||||
}
|
||||
tcs := []testcase{
|
||||
{
|
||||
name: "anonymous token lacks permissions",
|
||||
req: &pbpeering.TrustBundleListByServiceRequest{ServiceName: "api"},
|
||||
expectErr: "lacks permission 'service:write'",
|
||||
},
|
||||
{
|
||||
name: "service read token lacks permission",
|
||||
req: &pbpeering.TrustBundleListByServiceRequest{
|
||||
ServiceName: "api",
|
||||
},
|
||||
token: testTokenServiceReadSecret,
|
||||
expectErr: "lacks permission 'service:write'",
|
||||
},
|
||||
{
|
||||
name: "with service write token",
|
||||
req: &pbpeering.TrustBundleListByServiceRequest{
|
||||
ServiceName: "api",
|
||||
},
|
||||
token: testTokenServiceWriteSecret,
|
||||
expect: []string{"foo-root-1"},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
run(t, tc)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// newTestServer is copied from partition/service_test.go, with the addition of certs/cas.
|
||||
// TODO(peering): these are endpoint tests and should live in the agent/consul
|
||||
// package. Instead, these can be written around a mock client (see testing.go)
|
||||
|
@ -831,6 +1329,87 @@ func newDefaultDeps(t *testing.T, c *consul.Config) consul.Deps {
|
|||
}
|
||||
}
|
||||
|
||||
func upsertTestACLs(t *testing.T, store *state.Store) {
|
||||
var (
|
||||
testPolicyPeeringReadID = "43fed171-ad1d-4d3b-9df3-c99c1c835c37"
|
||||
testPolicyPeeringWriteID = "cddb0821-e720-4411-bbdd-cc62ce417eac"
|
||||
|
||||
testPolicyServiceReadID = "0e054136-f5d3-4627-a7e6-198f1df923d3"
|
||||
testPolicyServiceWriteID = "b55e03f4-c9dd-4210-8d24-f7ea8e2a1918"
|
||||
)
|
||||
policies := structs.ACLPolicies{
|
||||
{
|
||||
ID: testPolicyPeeringReadID,
|
||||
Name: "peering-read",
|
||||
Rules: `peering = "read"`,
|
||||
Syntax: acl.SyntaxCurrent,
|
||||
},
|
||||
{
|
||||
ID: testPolicyPeeringWriteID,
|
||||
Name: "peering-write",
|
||||
Rules: `peering = "write"`,
|
||||
Syntax: acl.SyntaxCurrent,
|
||||
},
|
||||
{
|
||||
ID: testPolicyServiceReadID,
|
||||
Name: "service-read",
|
||||
Rules: `service "api" { policy = "read" }`,
|
||||
Syntax: acl.SyntaxCurrent,
|
||||
},
|
||||
{
|
||||
ID: testPolicyServiceWriteID,
|
||||
Name: "service-write",
|
||||
Rules: `service "api" { policy = "write" }`,
|
||||
Syntax: acl.SyntaxCurrent,
|
||||
},
|
||||
}
|
||||
require.NoError(t, store.ACLPolicyBatchSet(100, policies))
|
||||
|
||||
tokens := structs.ACLTokens{
|
||||
&structs.ACLToken{
|
||||
AccessorID: "22500c91-723c-4335-be8a-6697417dc35b",
|
||||
SecretID: testTokenPeeringReadSecret,
|
||||
Description: "peering read",
|
||||
Policies: []structs.ACLTokenPolicyLink{
|
||||
{
|
||||
ID: testPolicyPeeringReadID,
|
||||
},
|
||||
},
|
||||
},
|
||||
&structs.ACLToken{
|
||||
AccessorID: "de924f93-cfec-404c-9a7e-c1c9b96b8cae",
|
||||
SecretID: testTokenPeeringWriteSecret,
|
||||
Description: "peering write",
|
||||
Policies: []structs.ACLTokenPolicyLink{
|
||||
{
|
||||
ID: testPolicyPeeringWriteID,
|
||||
},
|
||||
},
|
||||
},
|
||||
&structs.ACLToken{
|
||||
AccessorID: "53c54f79-ffed-47d4-904e-e2e0e40c0a01",
|
||||
SecretID: testTokenServiceReadSecret,
|
||||
Description: "service read",
|
||||
Policies: []structs.ACLTokenPolicyLink{
|
||||
{
|
||||
ID: testPolicyServiceReadID,
|
||||
},
|
||||
},
|
||||
},
|
||||
&structs.ACLToken{
|
||||
AccessorID: "a100fa5f-db72-49f0-8f61-aa1f9f92f657",
|
||||
SecretID: testTokenServiceWriteSecret,
|
||||
Description: "service write",
|
||||
Policies: []structs.ACLTokenPolicyLink{
|
||||
{
|
||||
ID: testPolicyServiceWriteID,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
require.NoError(t, store.ACLTokenBatchSet(101, tokens, state.ACLTokenSetOptions{}))
|
||||
}
|
||||
|
||||
func setupTestPeering(t *testing.T, store *state.Store, name string, index uint64) string {
|
||||
t.Helper()
|
||||
err := store.PeeringWrite(index, &pbpeering.Peering{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package peering
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/proto/pbpeering"
|
||||
)
|
||||
|
@ -53,6 +54,7 @@ func TestPeering(peerName string, state pbpeering.PeeringState, meta map[string]
|
|||
State: state,
|
||||
PeerID: validPeerID,
|
||||
Meta: meta,
|
||||
Partition: acl.DefaultPartitionName,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,9 +81,7 @@ type PeeringGenerateTokenRequest struct {
|
|||
PeerName string
|
||||
// Partition to be peered.
|
||||
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 is a mapping of some string value to any other string value
|
||||
Meta map[string]string `json:",omitempty"`
|
||||
// ServerExternalAddresses is a list of addresses to put into the generated token. This could be used to specify
|
||||
// load balancer(s) or external IPs to reach the servers from the dialing side, and will override any server
|
||||
|
@ -104,8 +102,6 @@ type PeeringEstablishRequest struct {
|
|||
PeeringToken string `json:",omitempty"`
|
||||
// Partition to be peered.
|
||||
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"`
|
||||
}
|
||||
|
|
|
@ -37,6 +37,97 @@ func peerExistsInPeerListings(peer *Peering, peerings []*Peering) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func TestAPI_Peering_ACLDeny(t *testing.T) {
|
||||
c, s := makeACLClient(t)
|
||||
defer s.Stop()
|
||||
|
||||
peerings := c.Peerings()
|
||||
|
||||
testutil.RunStep(t, "generate token", func(t *testing.T) {
|
||||
req := PeeringGenerateTokenRequest{PeerName: "peer1"}
|
||||
|
||||
testutil.RunStep(t, "without ACL token", func(t *testing.T) {
|
||||
_, _, err := peerings.GenerateToken(context.Background(), req, &WriteOptions{Token: "anonymous"})
|
||||
require.Error(t, err)
|
||||
testutil.RequireErrorContains(t, err, "Permission denied")
|
||||
})
|
||||
|
||||
testutil.RunStep(t, "with ACL token", func(t *testing.T) {
|
||||
resp, wm, err := peerings.GenerateToken(context.Background(), req, &WriteOptions{Token: "root"})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, wm)
|
||||
require.NotNil(t, resp)
|
||||
})
|
||||
})
|
||||
|
||||
testutil.RunStep(t, "establish peering", func(t *testing.T) {
|
||||
tokenJSON := `{"ServerAddresses":["127.0.0.1:8502"],"ServerName":"foo","PeerID":"716af65f-b844-f3bb-8aef-cfd7949f6873"}`
|
||||
tokenB64 := base64.StdEncoding.EncodeToString([]byte(tokenJSON))
|
||||
|
||||
req := PeeringEstablishRequest{
|
||||
PeerName: "peer2",
|
||||
PeeringToken: tokenB64,
|
||||
}
|
||||
testutil.RunStep(t, "without ACL token", func(t *testing.T) {
|
||||
_, _, err := peerings.Establish(context.Background(), req, &WriteOptions{Token: "anonymous"})
|
||||
require.Error(t, err)
|
||||
testutil.RequireErrorContains(t, err, "Permission denied")
|
||||
})
|
||||
|
||||
testutil.RunStep(t, "with ACL token", func(t *testing.T) {
|
||||
resp, wm, err := peerings.Establish(context.Background(), req, &WriteOptions{Token: "root"})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, wm)
|
||||
require.NotNil(t, resp)
|
||||
})
|
||||
})
|
||||
|
||||
testutil.RunStep(t, "read peering", func(t *testing.T) {
|
||||
testutil.RunStep(t, "without ACL token", func(t *testing.T) {
|
||||
_, _, err := peerings.Read(context.Background(), "peer1", &QueryOptions{Token: "anonymous"})
|
||||
require.Error(t, err)
|
||||
testutil.RequireErrorContains(t, err, "Permission denied")
|
||||
})
|
||||
|
||||
testutil.RunStep(t, "with ACL token", func(t *testing.T) {
|
||||
resp, qm, err := peerings.Read(context.Background(), "peer1", &QueryOptions{Token: "root"})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, qm)
|
||||
require.NotNil(t, resp)
|
||||
})
|
||||
})
|
||||
|
||||
testutil.RunStep(t, "list peerings", func(t *testing.T) {
|
||||
testutil.RunStep(t, "without ACL token", func(t *testing.T) {
|
||||
_, _, err := peerings.List(context.Background(), &QueryOptions{Token: "anonymous"})
|
||||
require.Error(t, err)
|
||||
testutil.RequireErrorContains(t, err, "Permission denied")
|
||||
})
|
||||
|
||||
testutil.RunStep(t, "with ACL token", func(t *testing.T) {
|
||||
resp, qm, err := peerings.List(context.Background(), &QueryOptions{Token: "root"})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, qm)
|
||||
require.NotNil(t, resp)
|
||||
require.Len(t, resp, 2)
|
||||
})
|
||||
})
|
||||
|
||||
testutil.RunStep(t, "delete peering", func(t *testing.T) {
|
||||
testutil.RunStep(t, "without ACL token", func(t *testing.T) {
|
||||
_, err := peerings.Delete(context.Background(), "peer1", &WriteOptions{Token: "anonymous"})
|
||||
require.Error(t, err)
|
||||
testutil.RequireErrorContains(t, err, "Permission denied")
|
||||
})
|
||||
|
||||
testutil.RunStep(t, "with ACL token", func(t *testing.T) {
|
||||
wm, err := peerings.Delete(context.Background(), "peer1", &WriteOptions{Token: "root"})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, wm)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestAPI_Peering_Read_ErrorHandling(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -115,25 +206,6 @@ func TestAPI_Peering_List(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
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
|
||||
_, _, err := peerings.GenerateToken(ctx, PeeringGenerateTokenRequest{PeerName: "peer2", Datacenter: "dc2"}, nil)
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAPI_Peering_GenerateToken_ExternalAddresses(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -163,9 +235,6 @@ func TestAPI_Peering_GenerateToken_ExternalAddresses(t *testing.T) {
|
|||
require.Contains(t, string(tokenJSON), externalAddress)
|
||||
}
|
||||
|
||||
// TODO(peering): cover the following test cases: bad/ malformed input, peering with wrong token,
|
||||
// peering with the wrong PeerName
|
||||
|
||||
// TestAPI_Peering_GenerateToken_Read_Establish_Delete tests the following use case:
|
||||
// a server creates a peering token, reads the token, then another server calls establish peering
|
||||
// finally, we delete the token on the first server
|
||||
|
@ -217,7 +286,6 @@ func TestAPI_Peering_GenerateToken_Read_Establish_Delete(t *testing.T) {
|
|||
|
||||
testutil.RunStep(t, "establish peering", func(t *testing.T) {
|
||||
i := PeeringEstablishRequest{
|
||||
Datacenter: c2.config.Datacenter,
|
||||
PeerName: "peer1",
|
||||
PeeringToken: token1,
|
||||
Meta: map[string]string{"foo": "bar"},
|
||||
|
|
|
@ -11,8 +11,6 @@ func EstablishRequestToAPI(s *EstablishRequest, t *api.PeeringEstablishRequest)
|
|||
t.PeerName = s.PeerName
|
||||
t.PeeringToken = s.PeeringToken
|
||||
t.Partition = s.Partition
|
||||
t.Datacenter = s.Datacenter
|
||||
t.Token = s.Token
|
||||
t.Meta = s.Meta
|
||||
}
|
||||
func EstablishRequestFromAPI(t *api.PeeringEstablishRequest, s *EstablishRequest) {
|
||||
|
@ -22,8 +20,6 @@ func EstablishRequestFromAPI(t *api.PeeringEstablishRequest, s *EstablishRequest
|
|||
s.PeerName = t.PeerName
|
||||
s.PeeringToken = t.PeeringToken
|
||||
s.Partition = t.Partition
|
||||
s.Datacenter = t.Datacenter
|
||||
s.Token = t.Token
|
||||
s.Meta = t.Meta
|
||||
}
|
||||
func EstablishResponseToAPI(s *EstablishResponse, t *api.PeeringEstablishResponse) {
|
||||
|
@ -42,8 +38,6 @@ func GenerateTokenRequestToAPI(s *GenerateTokenRequest, t *api.PeeringGenerateTo
|
|||
}
|
||||
t.PeerName = s.PeerName
|
||||
t.Partition = s.Partition
|
||||
t.Datacenter = s.Datacenter
|
||||
t.Token = s.Token
|
||||
t.Meta = s.Meta
|
||||
t.ServerExternalAddresses = s.ServerExternalAddresses
|
||||
}
|
||||
|
@ -53,8 +47,6 @@ func GenerateTokenRequestFromAPI(t *api.PeeringGenerateTokenRequest, s *Generate
|
|||
}
|
||||
s.PeerName = t.PeerName
|
||||
s.Partition = t.Partition
|
||||
s.Datacenter = t.Datacenter
|
||||
s.Token = t.Token
|
||||
s.Meta = t.Meta
|
||||
s.ServerExternalAddresses = t.ServerExternalAddresses
|
||||
}
|
||||
|
|
|
@ -1,86 +1,68 @@
|
|||
package pbpeering
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/timestamp"
|
||||
"github.com/mitchellh/hashstructure"
|
||||
|
||||
"github.com/hashicorp/consul/agent/cache"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/lib"
|
||||
)
|
||||
|
||||
// TODO(peering): These are byproducts of not embedding
|
||||
// types in our protobuf definitions and are temporary;
|
||||
// Hoping to replace them with 1 or 2 methods per request
|
||||
// using https://github.com/hashicorp/consul/pull/12507
|
||||
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (req *GenerateTokenRequest) RequestDatacenter() string {
|
||||
return req.Datacenter
|
||||
// Cross-datacenter requests are not allowed for peering actions because
|
||||
// they rely on WAN-federation.
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsRead implements structs.RPCInfo
|
||||
func (req *GenerateTokenRequest) IsRead() bool {
|
||||
return false
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (req *EstablishRequest) RequestDatacenter() string {
|
||||
// Cross-datacenter requests are not allowed for peering actions because
|
||||
// they rely on WAN-federation.
|
||||
return ""
|
||||
}
|
||||
|
||||
// AllowStaleRead implements structs.RPCInfo
|
||||
func (req *GenerateTokenRequest) AllowStaleRead() bool {
|
||||
return false
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (req *PeeringReadRequest) RequestDatacenter() string {
|
||||
// Cross-datacenter requests are not allowed for peering actions because
|
||||
// they rely on WAN-federation.
|
||||
return ""
|
||||
}
|
||||
|
||||
// TokenSecret implements structs.RPCInfo
|
||||
func (req *GenerateTokenRequest) TokenSecret() string {
|
||||
return req.Token
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (req *PeeringListRequest) RequestDatacenter() string {
|
||||
// Cross-datacenter requests are not allowed for peering actions because
|
||||
// they rely on WAN-federation.
|
||||
return ""
|
||||
}
|
||||
|
||||
// SetTokenSecret implements structs.RPCInfo
|
||||
func (req *GenerateTokenRequest) SetTokenSecret(token string) {
|
||||
req.Token = token
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (req *PeeringWriteRequest) RequestDatacenter() string {
|
||||
// Cross-datacenter requests are not allowed for peering actions because
|
||||
// they rely on WAN-federation.
|
||||
return ""
|
||||
}
|
||||
|
||||
// HasTimedOut implements structs.RPCInfo
|
||||
func (req *GenerateTokenRequest) HasTimedOut(start time.Time, rpcHoldTimeout, _, _ time.Duration) (bool, error) {
|
||||
return time.Since(start) > rpcHoldTimeout, nil
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (req *PeeringDeleteRequest) RequestDatacenter() string {
|
||||
// Cross-datacenter requests are not allowed for peering actions because
|
||||
// they rely on WAN-federation.
|
||||
return ""
|
||||
}
|
||||
|
||||
// Timeout implements structs.RPCInfo
|
||||
func (msg *GenerateTokenRequest) Timeout(rpcHoldTimeout time.Duration, maxQueryTime time.Duration, defaultQueryTime time.Duration) time.Duration {
|
||||
return rpcHoldTimeout
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (req *TrustBundleReadRequest) RequestDatacenter() string {
|
||||
// Cross-datacenter requests are not allowed for peering actions because
|
||||
// they rely on WAN-federation.
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsRead implements structs.RPCInfo
|
||||
func (req *EstablishRequest) IsRead() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// AllowStaleRead implements structs.RPCInfo
|
||||
func (req *EstablishRequest) AllowStaleRead() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// TokenSecret implements structs.RPCInfo
|
||||
func (req *EstablishRequest) TokenSecret() string {
|
||||
return req.Token
|
||||
}
|
||||
|
||||
// SetTokenSecret implements structs.RPCInfo
|
||||
func (req *EstablishRequest) SetTokenSecret(token string) {
|
||||
req.Token = token
|
||||
}
|
||||
|
||||
// HasTimedOut implements structs.RPCInfo
|
||||
func (req *EstablishRequest) HasTimedOut(start time.Time, rpcHoldTimeout, _, _ time.Duration) (bool, error) {
|
||||
return time.Since(start) > rpcHoldTimeout, nil
|
||||
}
|
||||
|
||||
// Timeout implements structs.RPCInfo
|
||||
func (msg *EstablishRequest) Timeout(rpcHoldTimeout time.Duration, maxQueryTime time.Duration, defaultQueryTime time.Duration) time.Duration {
|
||||
return rpcHoldTimeout
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (req *TrustBundleListByServiceRequest) RequestDatacenter() string {
|
||||
// Cross-datacenter requests are not allowed for peering actions because
|
||||
// they rely on WAN-federation.
|
||||
return ""
|
||||
}
|
||||
|
||||
// ShouldDial returns true when the peering was stored via the peering initiation endpoint,
|
||||
|
@ -95,34 +77,6 @@ func (x PeeringState) GoString() string {
|
|||
return x.String()
|
||||
}
|
||||
|
||||
func (r *TrustBundleReadRequest) CacheInfo() cache.RequestInfo {
|
||||
info := cache.RequestInfo{
|
||||
// TODO(peering): Revisit whether this is the token to use once request types accept a token.
|
||||
Token: r.Token(),
|
||||
Datacenter: r.Datacenter,
|
||||
MinIndex: 0,
|
||||
Timeout: 0,
|
||||
MustRevalidate: false,
|
||||
|
||||
// TODO(peering): Cache.notifyPollingQuery polls at this interval. We need to revisit how that polling works.
|
||||
// Using an exponential backoff when the result hasn't changed may be preferable.
|
||||
MaxAge: 1 * time.Second,
|
||||
}
|
||||
|
||||
v, err := hashstructure.Hash([]interface{}{
|
||||
r.Partition,
|
||||
r.Name,
|
||||
}, nil)
|
||||
if err == nil {
|
||||
// If there is an error, we don't set the key. A blank key forces
|
||||
// no cache for this request so the request is forwarded directly
|
||||
// to the server.
|
||||
info.Key = strconv.FormatUint(v, 10)
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
// ConcatenatedRootPEMs concatenates and returns all PEM-encoded public certificates
|
||||
// in a peer's trust bundle.
|
||||
func (b *PeeringTrustBundle) ConcatenatedRootPEMs() string {
|
||||
|
@ -242,35 +196,6 @@ func NewEstablishRequestFromAPI(req *api.PeeringEstablishRequest) *EstablishRequ
|
|||
return t
|
||||
}
|
||||
|
||||
func (r *TrustBundleListByServiceRequest) CacheInfo() cache.RequestInfo {
|
||||
info := cache.RequestInfo{
|
||||
// TODO(peering): Revisit whether this is the token to use once request types accept a token.
|
||||
Token: r.Token(),
|
||||
Datacenter: r.Datacenter,
|
||||
MinIndex: 0,
|
||||
Timeout: 0,
|
||||
MustRevalidate: false,
|
||||
|
||||
// TODO(peering): Cache.notifyPollingQuery polls at this interval. We need to revisit how that polling works.
|
||||
// Using an exponential backoff when the result hasn't changed may be preferable.
|
||||
MaxAge: 1 * time.Second,
|
||||
}
|
||||
|
||||
v, err := hashstructure.Hash([]interface{}{
|
||||
r.Partition,
|
||||
r.Namespace,
|
||||
r.ServiceName,
|
||||
}, nil)
|
||||
if err == nil {
|
||||
// If there is an error, we don't set the key. A blank key forces
|
||||
// no cache for this request so the request is forwarded directly
|
||||
// to the server.
|
||||
info.Key = strconv.FormatUint(v, 10)
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
func TimePtrFromProto(s *timestamp.Timestamp) *time.Time {
|
||||
if s == nil {
|
||||
return nil
|
||||
|
|
|
@ -140,9 +140,11 @@ type Peering struct {
|
|||
// ExportedServiceCount is the count of how many services are exported to this peering.
|
||||
ExportedServiceCount uint64 `protobuf:"varint,14,opt,name=ExportedServiceCount,proto3" json:"ExportedServiceCount,omitempty"`
|
||||
// CreateIndex is the Raft index at which the Peering was created.
|
||||
CreateIndex uint64 `protobuf:"varint,11,opt,name=CreateIndex,proto3" json:"CreateIndex,omitempty"`
|
||||
// @gotags: bexpr:"-"
|
||||
CreateIndex uint64 `protobuf:"varint,11,opt,name=CreateIndex,proto3" json:"CreateIndex,omitempty" bexpr:"-"`
|
||||
// ModifyIndex is the latest Raft index at which the Peering. was modified.
|
||||
ModifyIndex uint64 `protobuf:"varint,12,opt,name=ModifyIndex,proto3" json:"ModifyIndex,omitempty"`
|
||||
// @gotags: bexpr:"-"
|
||||
ModifyIndex uint64 `protobuf:"varint,12,opt,name=ModifyIndex,proto3" json:"ModifyIndex,omitempty" bexpr:"-"`
|
||||
}
|
||||
|
||||
func (x *Peering) Reset() {
|
||||
|
@ -293,9 +295,11 @@ type PeeringTrustBundle struct {
|
|||
// which sent this trust bundle. Used for generating SpiffeIDs.
|
||||
ExportedPartition string `protobuf:"bytes,5,opt,name=ExportedPartition,proto3" json:"ExportedPartition,omitempty"`
|
||||
// CreateIndex is the Raft index at which the trust domain was created.
|
||||
CreateIndex uint64 `protobuf:"varint,6,opt,name=CreateIndex,proto3" json:"CreateIndex,omitempty"`
|
||||
// @gotags: bexpr:"-"
|
||||
CreateIndex uint64 `protobuf:"varint,6,opt,name=CreateIndex,proto3" json:"CreateIndex,omitempty" bexpr:"-"`
|
||||
// ModifyIndex is the latest Raft index at which the trust bundle was modified.
|
||||
ModifyIndex uint64 `protobuf:"varint,7,opt,name=ModifyIndex,proto3" json:"ModifyIndex,omitempty"`
|
||||
// @gotags: bexpr:"-"
|
||||
ModifyIndex uint64 `protobuf:"varint,7,opt,name=ModifyIndex,proto3" json:"ModifyIndex,omitempty" bexpr:"-"`
|
||||
}
|
||||
|
||||
func (x *PeeringTrustBundle) Reset() {
|
||||
|
@ -379,7 +383,7 @@ func (x *PeeringTrustBundle) GetModifyIndex() uint64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,LeaderReadTODO
|
||||
// @consul-rpc-glue: LeaderReadTODO
|
||||
type PeeringReadRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -387,7 +391,6 @@ type PeeringReadRequest struct {
|
|||
|
||||
Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
|
||||
Partition string `protobuf:"bytes,2,opt,name=Partition,proto3" json:"Partition,omitempty"`
|
||||
Datacenter string `protobuf:"bytes,3,opt,name=Datacenter,proto3" json:"Datacenter,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PeeringReadRequest) Reset() {
|
||||
|
@ -436,13 +439,6 @@ func (x *PeeringReadRequest) GetPartition() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *PeeringReadRequest) GetDatacenter() string {
|
||||
if x != nil {
|
||||
return x.Datacenter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type PeeringReadResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -490,14 +486,13 @@ func (x *PeeringReadResponse) GetPeering() *Peering {
|
|||
return nil
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,LeaderReadTODO
|
||||
// @consul-rpc-glue: LeaderReadTODO
|
||||
type PeeringListRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Partition string `protobuf:"bytes,1,opt,name=Partition,proto3" json:"Partition,omitempty"`
|
||||
Datacenter string `protobuf:"bytes,2,opt,name=Datacenter,proto3" json:"Datacenter,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PeeringListRequest) Reset() {
|
||||
|
@ -539,13 +534,6 @@ func (x *PeeringListRequest) GetPartition() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *PeeringListRequest) GetDatacenter() string {
|
||||
if x != nil {
|
||||
return x.Datacenter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type PeeringListResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -593,17 +581,14 @@ func (x *PeeringListResponse) GetPeerings() []*Peering {
|
|||
return nil
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,WriteTODO
|
||||
type PeeringWriteRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Peering *Peering `protobuf:"bytes,1,opt,name=Peering,proto3" json:"Peering,omitempty"`
|
||||
//TODO(peering): what to do with embedded write request?
|
||||
Datacenter string `protobuf:"bytes,2,opt,name=Datacenter,proto3" json:"Datacenter,omitempty"`
|
||||
// Meta is a mapping of some string value to any other string value
|
||||
Meta map[string]string `protobuf:"bytes,3,rep,name=Meta,proto3" json:"Meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Meta map[string]string `protobuf:"bytes,2,rep,name=Meta,proto3" json:"Meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
}
|
||||
|
||||
func (x *PeeringWriteRequest) Reset() {
|
||||
|
@ -645,13 +630,6 @@ func (x *PeeringWriteRequest) GetPeering() *Peering {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *PeeringWriteRequest) GetDatacenter() string {
|
||||
if x != nil {
|
||||
return x.Datacenter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PeeringWriteRequest) GetMeta() map[string]string {
|
||||
if x != nil {
|
||||
return x.Meta
|
||||
|
@ -698,7 +676,6 @@ func (*PeeringWriteResponse) Descriptor() ([]byte, []int) {
|
|||
return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,WriteTODO
|
||||
type PeeringDeleteRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -706,8 +683,6 @@ type PeeringDeleteRequest struct {
|
|||
|
||||
Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
|
||||
Partition string `protobuf:"bytes,2,opt,name=Partition,proto3" json:"Partition,omitempty"`
|
||||
//TODO(peering): what to do with embedded write request?
|
||||
Datacenter string `protobuf:"bytes,3,opt,name=Datacenter,proto3" json:"Datacenter,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PeeringDeleteRequest) Reset() {
|
||||
|
@ -756,13 +731,6 @@ func (x *PeeringDeleteRequest) GetPartition() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *PeeringDeleteRequest) GetDatacenter() string {
|
||||
if x != nil {
|
||||
return x.Datacenter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type PeeringDeleteResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -801,7 +769,6 @@ func (*PeeringDeleteResponse) Descriptor() ([]byte, []int) {
|
|||
return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,ReadTODO
|
||||
type TrustBundleListByServiceRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -811,9 +778,6 @@ type TrustBundleListByServiceRequest struct {
|
|||
Namespace string `protobuf:"bytes,2,opt,name=Namespace,proto3" json:"Namespace,omitempty"`
|
||||
Partition string `protobuf:"bytes,3,opt,name=Partition,proto3" json:"Partition,omitempty"`
|
||||
Kind string `protobuf:"bytes,4,opt,name=Kind,proto3" json:"Kind,omitempty"`
|
||||
// these are common fields required for implementing structs.RPCInfo methods
|
||||
// that are used to forward requests
|
||||
Datacenter string `protobuf:"bytes,5,opt,name=Datacenter,proto3" json:"Datacenter,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TrustBundleListByServiceRequest) Reset() {
|
||||
|
@ -876,13 +840,6 @@ func (x *TrustBundleListByServiceRequest) GetKind() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *TrustBundleListByServiceRequest) GetDatacenter() string {
|
||||
if x != nil {
|
||||
return x.Datacenter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type TrustBundleListByServiceResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -938,7 +895,6 @@ func (x *TrustBundleListByServiceResponse) GetBundles() []*PeeringTrustBundle {
|
|||
return nil
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,ReadTODO
|
||||
type TrustBundleReadRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -946,9 +902,6 @@ type TrustBundleReadRequest struct {
|
|||
|
||||
Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
|
||||
Partition string `protobuf:"bytes,2,opt,name=Partition,proto3" json:"Partition,omitempty"`
|
||||
// these are common fields required for implementing structs.RPCInfo methods
|
||||
// that are used to forward requests
|
||||
Datacenter string `protobuf:"bytes,3,opt,name=Datacenter,proto3" json:"Datacenter,omitempty"`
|
||||
}
|
||||
|
||||
func (x *TrustBundleReadRequest) Reset() {
|
||||
|
@ -997,13 +950,6 @@ func (x *TrustBundleReadRequest) GetPartition() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *TrustBundleReadRequest) GetDatacenter() string {
|
||||
if x != nil {
|
||||
return x.Datacenter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type TrustBundleReadResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -1059,6 +1005,7 @@ func (x *TrustBundleReadResponse) GetBundle() *PeeringTrustBundle {
|
|||
return nil
|
||||
}
|
||||
|
||||
// This is a purely internal type and does not require query metadata.
|
||||
type PeeringTerminateByIDRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -1144,15 +1091,12 @@ func (*PeeringTerminateByIDResponse) Descriptor() ([]byte, []int) {
|
|||
return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{15}
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter
|
||||
type PeeringTrustBundleWriteRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
PeeringTrustBundle *PeeringTrustBundle `protobuf:"bytes,1,opt,name=PeeringTrustBundle,proto3" json:"PeeringTrustBundle,omitempty"`
|
||||
//TODO(peering): what to do with embedded write request?
|
||||
Datacenter string `protobuf:"bytes,2,opt,name=Datacenter,proto3" json:"Datacenter,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PeeringTrustBundleWriteRequest) Reset() {
|
||||
|
@ -1194,13 +1138,6 @@ func (x *PeeringTrustBundleWriteRequest) GetPeeringTrustBundle() *PeeringTrustBu
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *PeeringTrustBundleWriteRequest) GetDatacenter() string {
|
||||
if x != nil {
|
||||
return x.Datacenter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type PeeringTrustBundleWriteResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -1239,7 +1176,6 @@ func (*PeeringTrustBundleWriteResponse) Descriptor() ([]byte, []int) {
|
|||
return file_proto_pbpeering_peering_proto_rawDescGZIP(), []int{17}
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter
|
||||
type PeeringTrustBundleDeleteRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -1247,8 +1183,6 @@ type PeeringTrustBundleDeleteRequest struct {
|
|||
|
||||
Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
|
||||
Partition string `protobuf:"bytes,2,opt,name=Partition,proto3" json:"Partition,omitempty"`
|
||||
//TODO(peering): what to do with embedded write request?
|
||||
Datacenter string `protobuf:"bytes,3,opt,name=Datacenter,proto3" json:"Datacenter,omitempty"`
|
||||
}
|
||||
|
||||
func (x *PeeringTrustBundleDeleteRequest) Reset() {
|
||||
|
@ -1297,13 +1231,6 @@ func (x *PeeringTrustBundleDeleteRequest) GetPartition() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *PeeringTrustBundleDeleteRequest) GetDatacenter() string {
|
||||
if x != nil {
|
||||
return x.Datacenter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type PeeringTrustBundleDeleteResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -1356,10 +1283,6 @@ type GenerateTokenRequest struct {
|
|||
PeerName string `protobuf:"bytes,1,opt,name=PeerName,proto3" json:"PeerName,omitempty"`
|
||||
// Partition is the local partition being peered.
|
||||
Partition string `protobuf:"bytes,2,opt,name=Partition,proto3" json:"Partition,omitempty"`
|
||||
// these are common fields required for implementing structs.RPCInfo methods
|
||||
// that are used to forward requests
|
||||
Datacenter string `protobuf:"bytes,3,opt,name=Datacenter,proto3" json:"Datacenter,omitempty"`
|
||||
Token string `protobuf:"bytes,4,opt,name=Token,proto3" json:"Token,omitempty"`
|
||||
// Meta is a mapping of some string value to any other string value
|
||||
Meta map[string]string `protobuf:"bytes,5,rep,name=Meta,proto3" json:"Meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
// ServerExternalAddresses is a list of addresses to put into the generated token. This could be used to specify
|
||||
|
@ -1414,20 +1337,6 @@ func (x *GenerateTokenRequest) GetPartition() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *GenerateTokenRequest) GetDatacenter() string {
|
||||
if x != nil {
|
||||
return x.Datacenter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GenerateTokenRequest) GetToken() string {
|
||||
if x != nil {
|
||||
return x.Token
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GenerateTokenRequest) GetMeta() map[string]string {
|
||||
if x != nil {
|
||||
return x.Meta
|
||||
|
@ -1496,8 +1405,6 @@ func (x *GenerateTokenResponse) GetPeeringToken() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter
|
||||
//
|
||||
// mog annotation:
|
||||
//
|
||||
// target=github.com/hashicorp/consul/api.PeeringEstablishRequest
|
||||
|
@ -1514,12 +1421,8 @@ type EstablishRequest struct {
|
|||
PeeringToken string `protobuf:"bytes,2,opt,name=PeeringToken,proto3" json:"PeeringToken,omitempty"`
|
||||
// Partition is the local partition being peered.
|
||||
Partition string `protobuf:"bytes,3,opt,name=Partition,proto3" json:"Partition,omitempty"`
|
||||
// these are common fields required for implementing structs.RPCInfo methods
|
||||
// that are used to forward requests
|
||||
Datacenter string `protobuf:"bytes,4,opt,name=Datacenter,proto3" json:"Datacenter,omitempty"`
|
||||
Token string `protobuf:"bytes,5,opt,name=Token,proto3" json:"Token,omitempty"`
|
||||
// Meta is a mapping of some string value to any other string value
|
||||
Meta map[string]string `protobuf:"bytes,6,rep,name=Meta,proto3" json:"Meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Meta map[string]string `protobuf:"bytes,4,rep,name=Meta,proto3" json:"Meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
}
|
||||
|
||||
func (x *EstablishRequest) Reset() {
|
||||
|
@ -1575,20 +1478,6 @@ func (x *EstablishRequest) GetPartition() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *EstablishRequest) GetDatacenter() string {
|
||||
if x != nil {
|
||||
return x.Datacenter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EstablishRequest) GetToken() string {
|
||||
if x != nil {
|
||||
return x.Token
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EstablishRequest) GetMeta() map[string]string {
|
||||
if x != nil {
|
||||
return x.Meta
|
||||
|
@ -1596,7 +1485,6 @@ func (x *EstablishRequest) GetMeta() map[string]string {
|
|||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// mog annotation:
|
||||
//
|
||||
// target=github.com/hashicorp/consul/api.PeeringEstablishResponse
|
||||
|
@ -1706,39 +1594,33 @@ var file_proto_pbpeering_peering_proto_rawDesc = []byte{
|
|||
0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x49, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x49,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x22, 0x66, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x22, 0x46, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52,
|
||||
0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a,
|
||||
0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x5b, 0x0a, 0x13,
|
||||
0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5b, 0x0a, 0x13,
|
||||
0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67,
|
||||
0x52, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x52, 0x0a, 0x12, 0x50, 0x65, 0x65,
|
||||
0x52, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x32, 0x0a, 0x12, 0x50, 0x65, 0x65,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a,
|
||||
0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x5d, 0x0a,
|
||||
0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5d, 0x0a,
|
||||
0x13, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x73,
|
||||
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
|
||||
0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x52, 0x08, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x8a, 0x02, 0x0a,
|
||||
0x6e, 0x67, 0x52, 0x08, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xea, 0x01, 0x0a,
|
||||
0x13, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
|
||||
0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
||||
0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e,
|
||||
0x67, 0x52, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x61,
|
||||
0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x04, 0x4d, 0x65,
|
||||
0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
|
||||
0x67, 0x52, 0x07, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x54, 0x0a, 0x04, 0x4d, 0x65,
|
||||
0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
|
@ -1748,15 +1630,13 @@ var file_proto_pbpeering_peering_proto_rawDesc = []byte{
|
|||
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x16, 0x0a, 0x14, 0x50, 0x65, 0x65,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x68, 0x0a, 0x14, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65,
|
||||
0x65, 0x22, 0x48, 0x0a, 0x14, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65,
|
||||
0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d,
|
||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x44,
|
||||
0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x17, 0x0a, 0x15, 0x50,
|
||||
0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x17, 0x0a, 0x15, 0x50,
|
||||
0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x1f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x93, 0x01, 0x0a, 0x1f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75,
|
||||
0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x53,
|
||||
|
@ -1765,9 +1645,7 @@ var file_proto_pbpeering_peering_proto_rawDesc = []byte{
|
|||
0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74,
|
||||
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72,
|
||||
0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x61,
|
||||
0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x89, 0x01, 0x0a, 0x20, 0x54,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0x89, 0x01, 0x0a, 0x20, 0x54,
|
||||
0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79,
|
||||
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05,
|
||||
|
@ -1776,14 +1654,12 @@ var file_proto_pbpeering_peering_proto_rawDesc = []byte{
|
|||
0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x07, 0x42,
|
||||
0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x22, 0x6a, 0x0a, 0x16, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42,
|
||||
0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x22, 0x4a, 0x0a, 0x16, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42,
|
||||
0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x22, 0x7e, 0x0a, 0x17, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c,
|
||||
0x6f, 0x6e, 0x22, 0x7e, 0x0a, 0x17, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c,
|
||||
0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x49, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x12, 0x4d, 0x0a, 0x06, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x02, 0x20,
|
||||
|
@ -1796,7 +1672,7 @@ var file_proto_pbpeering_peering_proto_rawDesc = []byte{
|
|||
0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49,
|
||||
0x44, 0x22, 0x1e, 0x0a, 0x1c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x72, 0x6d,
|
||||
0x69, 0x6e, 0x61, 0x74, 0x65, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0xa7, 0x01, 0x0a, 0x1e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75,
|
||||
0x65, 0x22, 0x87, 0x01, 0x0a, 0x1e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75,
|
||||
0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x65, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54,
|
||||
0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
|
@ -1804,159 +1680,149 @@ var file_proto_pbpeering_peering_proto_rawDesc = []byte{
|
|||
0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73,
|
||||
0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x12, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67,
|
||||
0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x44,
|
||||
0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x22, 0x21, 0x0a, 0x1f, 0x50,
|
||||
0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x50,
|
||||
0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c,
|
||||
0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x73,
|
||||
0x65, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x53,
|
||||
0x0a, 0x1f, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75,
|
||||
0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x22, 0x22, 0x0a, 0x20, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72,
|
||||
0x69, 0x6f, 0x6e, 0x22, 0x22, 0x0a, 0x20, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x72,
|
||||
0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd0, 0x02, 0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, 0x02, 0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65,
|
||||
0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x61,
|
||||
0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x54, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
|
||||
0x12, 0x55, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41,
|
||||
0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75,
|
||||
0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
|
||||
0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x04, 0x4d, 0x65,
|
||||
0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x6e,
|
||||
0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74,
|
||||
0x61, 0x12, 0x38, 0x0a, 0x17, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x72,
|
||||
0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x17, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4d,
|
||||
0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x3a, 0x02, 0x38, 0x01, 0x22, 0x3b, 0x0a, 0x15, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
|
||||
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a,
|
||||
0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x22, 0xfc, 0x01, 0x0a, 0x10, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e,
|
||||
0x67, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x51, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70,
|
||||
0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x38, 0x0a, 0x17, 0x53, 0x65, 0x72, 0x76, 0x65,
|
||||
0x72, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
|
||||
0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x17, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||
0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65,
|
||||
0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
|
||||
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3b, 0x0a, 0x15, 0x47, 0x65,
|
||||
0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xb2, 0x02, 0x0a, 0x10, 0x45, 0x73, 0x74, 0x61,
|
||||
0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
|
||||
0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
|
||||
0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x61,
|
||||
0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x54, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
|
||||
0x12, 0x51, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d,
|
||||
0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75,
|
||||
0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x2e, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d,
|
||||
0x65, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
|
||||
0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x13, 0x0a, 0x11,
|
||||
0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x2a, 0x73, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74,
|
||||
0x65, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00,
|
||||
0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a,
|
||||
0x0c, 0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12,
|
||||
0x0a, 0x0a, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x46,
|
||||
0x41, 0x49, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x45, 0x4c, 0x45,
|
||||
0x54, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e,
|
||||
0x41, 0x54, 0x45, 0x44, 0x10, 0x06, 0x32, 0xc0, 0x08, 0x0a, 0x0e, 0x50, 0x65, 0x65, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x0d, 0x47, 0x65,
|
||||
0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x37, 0x2e, 0x68, 0x61,
|
||||
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e,
|
||||
0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
|
||||
0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76,
|
||||
0x0a, 0x09, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x33, 0x2e, 0x68, 0x61,
|
||||
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e,
|
||||
0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x2e, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e,
|
||||
0x67, 0x52, 0x65, 0x61, 0x64, 0x12, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
|
||||
0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
||||
0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e,
|
||||
0x67, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68,
|
||||
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
|
||||
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67,
|
||||
0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x12, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
|
||||
0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x68, 0x61, 0x73,
|
||||
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50,
|
||||
0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x0d, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65,
|
||||
0x6c, 0x65, 0x74, 0x65, 0x12, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67,
|
||||
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e,
|
||||
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||
0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e,
|
||||
0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
|
||||
0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45,
|
||||
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
|
||||
0x22, 0x13, 0x0a, 0x11, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x73, 0x0a, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67,
|
||||
0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e,
|
||||
0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10,
|
||||
0x01, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x49, 0x4e,
|
||||
0x47, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x03, 0x12,
|
||||
0x0b, 0x0a, 0x07, 0x46, 0x41, 0x49, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08,
|
||||
0x44, 0x45, 0x4c, 0x45, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x45,
|
||||
0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, 0x10, 0x06, 0x32, 0xc0, 0x08, 0x0a, 0x0e, 0x50,
|
||||
0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x82, 0x01,
|
||||
0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
|
||||
0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73,
|
||||
0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xa3, 0x01, 0x0a, 0x18, 0x54, 0x72, 0x75,
|
||||
0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x53, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
|
||||
0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
||||
0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42,
|
||||
0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x43, 0x2e, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x47, 0x65, 0x6e,
|
||||
0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x76, 0x0a, 0x09, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12,
|
||||
0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73,
|
||||
0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x2e, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69,
|
||||
0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x0b, 0x50, 0x65,
|
||||
0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x12, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65,
|
||||
0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7c, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
|
||||
0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36,
|
||||
0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75,
|
||||
0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x0d, 0x50, 0x65, 0x65, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65,
|
||||
0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c,
|
||||
0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x0c, 0x50,
|
||||
0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x36, 0x2e, 0x68, 0x61,
|
||||
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e,
|
||||
0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
|
||||
0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57,
|
||||
0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0xa3, 0x01, 0x0a,
|
||||
0x18, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x72,
|
||||
0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x53,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x88,
|
||||
0x01, 0x0a, 0x0f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65,
|
||||
0x61, 0x64, 0x12, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70,
|
||||
0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64,
|
||||
0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x43, 0x2e,
|
||||
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||
0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e,
|
||||
0x67, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61,
|
||||
0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x8a, 0x02, 0x0a, 0x25, 0x63, 0x6f,
|
||||
0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73,
|
||||
0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x42, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
||||
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67,
|
||||
0xa2, 0x02, 0x04, 0x48, 0x43, 0x49, 0x50, 0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63,
|
||||
0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x6e, 0x61, 0x6c, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0xca, 0x02, 0x21, 0x48, 0x61,
|
||||
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0xe2,
|
||||
0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73,
|
||||
0x67, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x42, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x0f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64,
|
||||
0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x12, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
|
||||
0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74,
|
||||
0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x65,
|
||||
0x65, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c,
|
||||
0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x8a, 0x02,
|
||||
0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
|
||||
0x70, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x0c, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67,
|
||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f,
|
||||
0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x70, 0x65, 0x65,
|
||||
0x72, 0x69, 0x6e, 0x67, 0xa2, 0x02, 0x04, 0x48, 0x43, 0x49, 0x50, 0xaa, 0x02, 0x21, 0x48, 0x61,
|
||||
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x49,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0xca,
|
||||
0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73,
|
||||
0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x50, 0x65, 0x65, 0x72,
|
||||
0x69, 0x6e, 0x67, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea,
|
||||
0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e,
|
||||
0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3a, 0x3a, 0x50,
|
||||
0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x69, 0x6e, 0x67, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c,
|
||||
0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c,
|
||||
0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64,
|
||||
0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a,
|
||||
0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
|
||||
0x6c, 0x3a, 0x3a, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -105,9 +105,11 @@ message Peering {
|
|||
uint64 ExportedServiceCount = 14;
|
||||
|
||||
// CreateIndex is the Raft index at which the Peering was created.
|
||||
// @gotags: bexpr:"-"
|
||||
uint64 CreateIndex = 11;
|
||||
|
||||
// ModifyIndex is the latest Raft index at which the Peering. was modified.
|
||||
// @gotags: bexpr:"-"
|
||||
uint64 ModifyIndex = 12;
|
||||
}
|
||||
|
||||
|
@ -130,79 +132,56 @@ message PeeringTrustBundle {
|
|||
string ExportedPartition = 5;
|
||||
|
||||
// CreateIndex is the Raft index at which the trust domain was created.
|
||||
// @gotags: bexpr:"-"
|
||||
uint64 CreateIndex = 6;
|
||||
|
||||
// ModifyIndex is the latest Raft index at which the trust bundle was modified.
|
||||
// @gotags: bexpr:"-"
|
||||
uint64 ModifyIndex = 7;
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,LeaderReadTODO
|
||||
// @consul-rpc-glue: LeaderReadTODO
|
||||
message PeeringReadRequest {
|
||||
string Name = 1;
|
||||
string Partition = 2;
|
||||
|
||||
string Datacenter = 3;
|
||||
|
||||
//TODO(peering) query metadata
|
||||
}
|
||||
|
||||
message PeeringReadResponse {
|
||||
Peering Peering = 1;
|
||||
|
||||
//TODO(peering) query metadata
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,LeaderReadTODO
|
||||
// @consul-rpc-glue: LeaderReadTODO
|
||||
message PeeringListRequest {
|
||||
string Partition = 1;
|
||||
|
||||
string Datacenter = 2;
|
||||
|
||||
//TODO(peering) query metadata
|
||||
}
|
||||
|
||||
message PeeringListResponse {
|
||||
repeated Peering Peerings = 1;
|
||||
|
||||
//TODO(peering) query metadata
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,WriteTODO
|
||||
message PeeringWriteRequest {
|
||||
Peering Peering = 1;
|
||||
|
||||
//TODO(peering): what to do with embedded write request?
|
||||
string Datacenter = 2;
|
||||
|
||||
// Meta is a mapping of some string value to any other string value
|
||||
map<string, string> Meta = 3;
|
||||
map<string, string> Meta = 2;
|
||||
}
|
||||
|
||||
// TODO(peering): Consider returning Peering if we keep this endpoint around
|
||||
message PeeringWriteResponse {}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,WriteTODO
|
||||
message PeeringDeleteRequest {
|
||||
string Name = 1;
|
||||
|
||||
string Partition = 2;
|
||||
|
||||
//TODO(peering): what to do with embedded write request?
|
||||
string Datacenter = 3;
|
||||
}
|
||||
|
||||
message PeeringDeleteResponse {}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,ReadTODO
|
||||
message TrustBundleListByServiceRequest {
|
||||
string ServiceName = 1;
|
||||
string Namespace = 2;
|
||||
string Partition = 3;
|
||||
string Kind = 4;
|
||||
|
||||
// these are common fields required for implementing structs.RPCInfo methods
|
||||
// that are used to forward requests
|
||||
string Datacenter = 5;
|
||||
}
|
||||
|
||||
message TrustBundleListByServiceResponse {
|
||||
|
@ -210,14 +189,9 @@ message TrustBundleListByServiceResponse {
|
|||
repeated PeeringTrustBundle Bundles = 2;
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter,ReadTODO
|
||||
message TrustBundleReadRequest {
|
||||
string Name = 1;
|
||||
string Partition = 2;
|
||||
|
||||
// these are common fields required for implementing structs.RPCInfo methods
|
||||
// that are used to forward requests
|
||||
string Datacenter = 3;
|
||||
}
|
||||
|
||||
message TrustBundleReadResponse {
|
||||
|
@ -225,30 +199,23 @@ message TrustBundleReadResponse {
|
|||
PeeringTrustBundle Bundle = 2;
|
||||
}
|
||||
|
||||
// This is a purely internal type and does not require query metadata.
|
||||
message PeeringTerminateByIDRequest {
|
||||
string ID = 1;
|
||||
}
|
||||
|
||||
message PeeringTerminateByIDResponse {}
|
||||
|
||||
// @consul-rpc-glue: Datacenter
|
||||
message PeeringTrustBundleWriteRequest {
|
||||
PeeringTrustBundle PeeringTrustBundle = 1;
|
||||
|
||||
//TODO(peering): what to do with embedded write request?
|
||||
string Datacenter = 2;
|
||||
}
|
||||
|
||||
message PeeringTrustBundleWriteResponse {}
|
||||
|
||||
// @consul-rpc-glue: Datacenter
|
||||
message PeeringTrustBundleDeleteRequest {
|
||||
string Name = 1;
|
||||
|
||||
string Partition = 2;
|
||||
|
||||
//TODO(peering): what to do with embedded write request?
|
||||
string Datacenter = 3;
|
||||
}
|
||||
|
||||
message PeeringTrustBundleDeleteResponse {}
|
||||
|
@ -265,11 +232,6 @@ message GenerateTokenRequest {
|
|||
// Partition is the local partition being peered.
|
||||
string Partition = 2;
|
||||
|
||||
// these are common fields required for implementing structs.RPCInfo methods
|
||||
// that are used to forward requests
|
||||
string Datacenter = 3;
|
||||
string Token = 4;
|
||||
|
||||
// Meta is a mapping of some string value to any other string value
|
||||
map<string, string> Meta = 5;
|
||||
|
||||
|
@ -290,8 +252,6 @@ message GenerateTokenResponse {
|
|||
string PeeringToken = 1;
|
||||
}
|
||||
|
||||
// @consul-rpc-glue: Datacenter
|
||||
//
|
||||
// mog annotation:
|
||||
//
|
||||
// target=github.com/hashicorp/consul/api.PeeringEstablishRequest
|
||||
|
@ -307,16 +267,10 @@ message EstablishRequest {
|
|||
// Partition is the local partition being peered.
|
||||
string Partition = 3;
|
||||
|
||||
// these are common fields required for implementing structs.RPCInfo methods
|
||||
// that are used to forward requests
|
||||
string Datacenter = 4;
|
||||
string Token = 5;
|
||||
|
||||
// Meta is a mapping of some string value to any other string value
|
||||
map<string, string> Meta = 6;
|
||||
map<string, string> Meta = 4;
|
||||
}
|
||||
|
||||
//
|
||||
// mog annotation:
|
||||
//
|
||||
// target=github.com/hashicorp/consul/api.PeeringEstablishResponse
|
||||
|
|
|
@ -12,14 +12,6 @@ import (
|
|||
var _ structs.RPCInfo
|
||||
var _ time.Month
|
||||
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (msg *PeeringReadRequest) RequestDatacenter() string {
|
||||
if msg == nil {
|
||||
return ""
|
||||
}
|
||||
return msg.Datacenter
|
||||
}
|
||||
|
||||
// IsRead implements structs.RPCInfo
|
||||
func (msg *PeeringReadRequest) IsRead() bool {
|
||||
// TODO(peering): figure out read semantics here
|
||||
|
@ -64,14 +56,6 @@ func (msg *PeeringReadRequest) Token() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (msg *PeeringListRequest) RequestDatacenter() string {
|
||||
if msg == nil {
|
||||
return ""
|
||||
}
|
||||
return msg.Datacenter
|
||||
}
|
||||
|
||||
// IsRead implements structs.RPCInfo
|
||||
func (msg *PeeringListRequest) IsRead() bool {
|
||||
// TODO(peering): figure out read semantics here
|
||||
|
@ -115,211 +99,3 @@ func (msg *PeeringListRequest) Token() string {
|
|||
// TODO(peering): figure out read semantics here
|
||||
return ""
|
||||
}
|
||||
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (msg *PeeringWriteRequest) RequestDatacenter() string {
|
||||
if msg == nil {
|
||||
return ""
|
||||
}
|
||||
return msg.Datacenter
|
||||
}
|
||||
|
||||
// IsRead implements structs.RPCInfo
|
||||
func (msg *PeeringWriteRequest) IsRead() bool {
|
||||
// TODO(peering): figure out write semantics here
|
||||
return false
|
||||
}
|
||||
|
||||
// AllowStaleRead implements structs.RPCInfo
|
||||
func (msg *PeeringWriteRequest) AllowStaleRead() bool {
|
||||
// TODO(peering): figure out write semantics here
|
||||
return false
|
||||
}
|
||||
|
||||
// HasTimedOut implements structs.RPCInfo
|
||||
func (msg *PeeringWriteRequest) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
|
||||
// TODO(peering): figure out write semantics here
|
||||
return time.Since(start) > rpcHoldTimeout, nil
|
||||
}
|
||||
|
||||
// Timeout implements structs.RPCInfo
|
||||
func (msg *PeeringWriteRequest) Timeout(rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) time.Duration {
|
||||
// TODO(peering): figure out write semantics here
|
||||
return rpcHoldTimeout
|
||||
}
|
||||
|
||||
// SetTokenSecret implements structs.RPCInfo
|
||||
func (msg *PeeringWriteRequest) SetTokenSecret(s string) {
|
||||
// TODO(peering): figure out write semantics here
|
||||
}
|
||||
|
||||
// TokenSecret implements structs.RPCInfo
|
||||
func (msg *PeeringWriteRequest) TokenSecret() string {
|
||||
// TODO(peering): figure out write semantics here
|
||||
return ""
|
||||
}
|
||||
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (msg *PeeringDeleteRequest) RequestDatacenter() string {
|
||||
if msg == nil {
|
||||
return ""
|
||||
}
|
||||
return msg.Datacenter
|
||||
}
|
||||
|
||||
// IsRead implements structs.RPCInfo
|
||||
func (msg *PeeringDeleteRequest) IsRead() bool {
|
||||
// TODO(peering): figure out write semantics here
|
||||
return false
|
||||
}
|
||||
|
||||
// AllowStaleRead implements structs.RPCInfo
|
||||
func (msg *PeeringDeleteRequest) AllowStaleRead() bool {
|
||||
// TODO(peering): figure out write semantics here
|
||||
return false
|
||||
}
|
||||
|
||||
// HasTimedOut implements structs.RPCInfo
|
||||
func (msg *PeeringDeleteRequest) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
|
||||
// TODO(peering): figure out write semantics here
|
||||
return time.Since(start) > rpcHoldTimeout, nil
|
||||
}
|
||||
|
||||
// Timeout implements structs.RPCInfo
|
||||
func (msg *PeeringDeleteRequest) Timeout(rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) time.Duration {
|
||||
// TODO(peering): figure out write semantics here
|
||||
return rpcHoldTimeout
|
||||
}
|
||||
|
||||
// SetTokenSecret implements structs.RPCInfo
|
||||
func (msg *PeeringDeleteRequest) SetTokenSecret(s string) {
|
||||
// TODO(peering): figure out write semantics here
|
||||
}
|
||||
|
||||
// TokenSecret implements structs.RPCInfo
|
||||
func (msg *PeeringDeleteRequest) TokenSecret() string {
|
||||
// TODO(peering): figure out write semantics here
|
||||
return ""
|
||||
}
|
||||
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (msg *TrustBundleListByServiceRequest) RequestDatacenter() string {
|
||||
if msg == nil {
|
||||
return ""
|
||||
}
|
||||
return msg.Datacenter
|
||||
}
|
||||
|
||||
// IsRead implements structs.RPCInfo
|
||||
func (msg *TrustBundleListByServiceRequest) IsRead() bool {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return true
|
||||
}
|
||||
|
||||
// AllowStaleRead implements structs.RPCInfo
|
||||
func (msg *TrustBundleListByServiceRequest) AllowStaleRead() bool {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return false
|
||||
}
|
||||
|
||||
// HasTimedOut implements structs.RPCInfo
|
||||
func (msg *TrustBundleListByServiceRequest) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return time.Since(start) > rpcHoldTimeout, nil
|
||||
}
|
||||
|
||||
// Timeout implements structs.RPCInfo
|
||||
func (msg *TrustBundleListByServiceRequest) Timeout(rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) time.Duration {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return rpcHoldTimeout
|
||||
}
|
||||
|
||||
// SetTokenSecret implements structs.RPCInfo
|
||||
func (msg *TrustBundleListByServiceRequest) SetTokenSecret(s string) {
|
||||
// TODO(peering): figure out read semantics here
|
||||
}
|
||||
|
||||
// TokenSecret implements structs.RPCInfo
|
||||
func (msg *TrustBundleListByServiceRequest) TokenSecret() string {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return ""
|
||||
}
|
||||
|
||||
// Token implements structs.RPCInfo
|
||||
func (msg *TrustBundleListByServiceRequest) Token() string {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return ""
|
||||
}
|
||||
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (msg *TrustBundleReadRequest) RequestDatacenter() string {
|
||||
if msg == nil {
|
||||
return ""
|
||||
}
|
||||
return msg.Datacenter
|
||||
}
|
||||
|
||||
// IsRead implements structs.RPCInfo
|
||||
func (msg *TrustBundleReadRequest) IsRead() bool {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return true
|
||||
}
|
||||
|
||||
// AllowStaleRead implements structs.RPCInfo
|
||||
func (msg *TrustBundleReadRequest) AllowStaleRead() bool {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return false
|
||||
}
|
||||
|
||||
// HasTimedOut implements structs.RPCInfo
|
||||
func (msg *TrustBundleReadRequest) HasTimedOut(start time.Time, rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) (bool, error) {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return time.Since(start) > rpcHoldTimeout, nil
|
||||
}
|
||||
|
||||
// Timeout implements structs.RPCInfo
|
||||
func (msg *TrustBundleReadRequest) Timeout(rpcHoldTimeout time.Duration, a time.Duration, b time.Duration) time.Duration {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return rpcHoldTimeout
|
||||
}
|
||||
|
||||
// SetTokenSecret implements structs.RPCInfo
|
||||
func (msg *TrustBundleReadRequest) SetTokenSecret(s string) {
|
||||
// TODO(peering): figure out read semantics here
|
||||
}
|
||||
|
||||
// TokenSecret implements structs.RPCInfo
|
||||
func (msg *TrustBundleReadRequest) TokenSecret() string {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return ""
|
||||
}
|
||||
|
||||
// Token implements structs.RPCInfo
|
||||
func (msg *TrustBundleReadRequest) Token() string {
|
||||
// TODO(peering): figure out read semantics here
|
||||
return ""
|
||||
}
|
||||
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (msg *PeeringTrustBundleWriteRequest) RequestDatacenter() string {
|
||||
if msg == nil {
|
||||
return ""
|
||||
}
|
||||
return msg.Datacenter
|
||||
}
|
||||
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (msg *PeeringTrustBundleDeleteRequest) RequestDatacenter() string {
|
||||
if msg == nil {
|
||||
return ""
|
||||
}
|
||||
return msg.Datacenter
|
||||
}
|
||||
|
||||
// RequestDatacenter implements structs.RPCInfo
|
||||
func (msg *EstablishRequest) RequestDatacenter() string {
|
||||
if msg == nil {
|
||||
return ""
|
||||
}
|
||||
return msg.Datacenter
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue