2023-03-28 18:39:22 +00:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
package peering
import (
2022-10-10 19:45:30 +00:00
"container/ring"
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
"context"
"errors"
"fmt"
"strings"
"time"
"github.com/armon/go-metrics"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-memdb"
2022-08-01 14:33:18 +00:00
"github.com/hashicorp/go-multierror"
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
grpcstatus "google.golang.org/grpc/status"
2022-07-19 18:43:29 +00:00
"google.golang.org/protobuf/proto"
2023-01-11 14:39:10 +00:00
"google.golang.org/protobuf/types/known/timestamppb"
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
"github.com/hashicorp/consul/acl"
2022-07-12 23:18:05 +00:00
"github.com/hashicorp/consul/acl/resolver"
2023-05-23 21:29:10 +00:00
"github.com/hashicorp/consul/agent/blockingquery"
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
"github.com/hashicorp/consul/agent/consul/state"
"github.com/hashicorp/consul/agent/consul/stream"
2022-07-12 23:18:05 +00:00
external "github.com/hashicorp/consul/agent/grpc-external"
2022-07-13 15:33:48 +00:00
"github.com/hashicorp/consul/agent/grpc-external/services/peerstream"
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
"github.com/hashicorp/consul/agent/structs"
2022-06-21 18:04:08 +00:00
"github.com/hashicorp/consul/lib"
2023-05-23 21:29:10 +00:00
"github.com/hashicorp/consul/lib/retry"
2023-03-10 14:36:15 +00:00
"github.com/hashicorp/consul/proto/private/pbcommon"
2023-02-17 21:14:46 +00:00
"github.com/hashicorp/consul/proto/private/pbpeering"
"github.com/hashicorp/consul/proto/private/pbpeerstream"
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
)
var (
errPeeringTokenInvalidCA = errors . New ( "peering token CA value is invalid" )
errPeeringTokenEmptyServerAddresses = errors . New ( "peering token server addresses value is empty" )
errPeeringTokenEmptyServerName = errors . New ( "peering token server name value is empty" )
errPeeringTokenEmptyPeerID = errors . New ( "peering token peer ID value is empty" )
)
2022-10-10 19:45:30 +00:00
const (
// meshGatewayWait is the initial wait on calls to exchange a secret with a peer when dialing through a gateway.
// This wait provides some time for the first gateway address to configure a route to the peer servers.
2022-11-10 18:54:00 +00:00
// This study shows latency distribution https://www.hashicorp.com/cgsb.
// With 1s we cover ~p96, then we initiate the 3-second retry loop.
meshGatewayWait = 1 * time . Second
establishmentTimeout = 3 * time . Second
2022-10-10 19:45:30 +00:00
)
2022-06-10 16:10:46 +00:00
// errPeeringInvalidServerAddress is returned when an establish request contains
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
// an invalid server address.
type errPeeringInvalidServerAddress struct {
addr string
}
// Error implements the error interface
func ( e * errPeeringInvalidServerAddress ) Error ( ) string {
return fmt . Sprintf ( "%s is not a valid peering server address" , e . addr )
}
2022-07-12 23:18:05 +00:00
// 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
}
2023-05-23 21:29:10 +00:00
type readRequest struct {
2022-07-12 23:18:05 +00:00
structs . QueryOptions
structs . DCSpecificRequest
}
2023-05-23 21:29:10 +00:00
var emptyDCSpecificRequest structs . DCSpecificRequest
2022-07-08 17:01:13 +00:00
// Server implements pbpeering.PeeringService to provide RPC operations for
// managing peering relationships.
type Server struct {
Config
}
2022-05-25 17:37:44 +00:00
type Config struct {
2022-07-08 17:01:13 +00:00
Backend Backend
Tracker * peerstream . Tracker
Logger hclog . Logger
ForwardRPC func ( structs . RPCInfo , func ( * grpc . ClientConn ) error ) ( bool , error )
2022-05-25 17:37:44 +00:00
Datacenter string
ConnectEnabled bool
2022-07-22 22:20:21 +00:00
PeeringEnabled bool
2023-03-10 14:36:15 +00:00
Locality * structs . Locality
2023-05-23 21:29:10 +00:00
// Needed because the stateful components needed to handle blocking queries are mixed in with server goo
FSMServer blockingquery . FSMServer
2022-05-25 17:37:44 +00:00
}
2022-07-08 17:01:13 +00:00
func NewServer ( cfg Config ) * Server {
requireNotNil ( cfg . Backend , "Backend" )
requireNotNil ( cfg . Tracker , "Tracker" )
requireNotNil ( cfg . Logger , "Logger" )
requireNotNil ( cfg . ForwardRPC , "ForwardRPC" )
2023-05-23 21:29:10 +00:00
requireNotNil ( cfg . FSMServer , "FSMServer" )
2022-07-08 17:01:13 +00:00
if cfg . Datacenter == "" {
panic ( "Datacenter is required" )
}
return & Server {
Config : cfg ,
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
}
2022-07-08 17:01:13 +00:00
func requireNotNil ( v interface { } , name string ) {
if v == nil {
panic ( name + " is required" )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
}
}
2022-07-08 17:01:13 +00:00
var _ pbpeering . PeeringServiceServer = ( * Server ) ( nil )
func ( s * Server ) Register ( grpcServer * grpc . Server ) {
pbpeering . RegisterPeeringServiceServer ( grpcServer , s )
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
// Backend defines the core integrations the Peering endpoint depends on. A
// functional implementation will integrate with various subcomponents of Consul
// such as the State store for reading and writing data, the CA machinery for
// providing access to CA data and the RPC system for forwarding requests to
// other servers.
type Backend interface {
2022-07-12 23:18:05 +00:00
// 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 )
2022-09-29 03:27:11 +00:00
// GetTLSMaterials returns the TLS materials for the dialer to dial the acceptor using TLS.
// It returns the server name to validate, and the CA certificate to validate with.
2022-09-29 21:49:58 +00:00
GetTLSMaterials ( generatingToken bool ) ( string , [ ] string , error )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
2022-10-10 19:45:30 +00:00
// GetLocalServerAddresses returns the addresses used for establishing a peering connection.
2022-09-20 13:46:20 +00:00
// These may be server addresses or mesh gateway addresses if peering through mesh gateways.
2022-10-10 19:45:30 +00:00
GetLocalServerAddresses ( ) ( [ ] string , error )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
// EncodeToken packages a peering token into a slice of bytes.
EncodeToken ( tok * structs . PeeringToken ) ( [ ] byte , error )
// DecodeToken unpackages a peering token from a slice of bytes.
DecodeToken ( [ ] byte ) ( * structs . PeeringToken , error )
2022-10-10 19:45:30 +00:00
// GetDialAddresses returns: the addresses to cycle through when dialing a peer's servers,
2022-11-10 18:54:00 +00:00
// an optional buffer of just gateway addresses, and an optional error.
2022-10-10 19:45:30 +00:00
// The resulting ring buffer is front-loaded with the local mesh gateway addresses if the local
// datacenter is configured to dial through mesh gateways.
2022-11-10 18:54:00 +00:00
GetDialAddresses ( logger hclog . Logger , ws memdb . WatchSet , peerID string ) ( * ring . Ring , * ring . Ring , error )
2022-10-10 19:45:30 +00:00
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
EnterpriseCheckPartitions ( partition string ) error
2022-06-08 16:55:18 +00:00
EnterpriseCheckNamespaces ( namespace string ) error
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
Subscribe ( req * stream . SubscribeRequest ) ( * stream . Subscription , error )
2022-05-23 18:30:58 +00:00
// IsLeader indicates whether the consul server is in a leader state or not.
IsLeader ( ) bool
2022-07-08 17:01:13 +00:00
// SetLeaderAddress is called on a raft.LeaderObservation in a go routine
// in the consul server; see trackLeaderChanges()
SetLeaderAddress ( string )
// GetLeaderAddress provides the best hint for the current address of the
// leader. There is no guarantee that this is the actual address of the
// leader.
GetLeaderAddress ( ) string
2022-05-27 00:55:16 +00:00
2022-08-01 14:33:18 +00:00
// CheckPeeringUUID returns true if the given UUID is not associated with
// an existing peering.
2022-07-08 17:01:13 +00:00
CheckPeeringUUID ( id string ) ( bool , error )
2022-08-01 14:33:18 +00:00
ValidateProposedPeeringSecret ( id string ) ( bool , error )
2022-07-08 17:01:13 +00:00
PeeringWrite ( req * pbpeering . PeeringWriteRequest ) error
Store ( ) Store
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
}
// Store provides a read-only interface for querying Peering data.
type Store interface {
PeeringRead ( ws memdb . WatchSet , q state . Query ) ( uint64 , * pbpeering . Peering , error )
2022-05-12 21:04:44 +00:00
PeeringReadByID ( ws memdb . WatchSet , id string ) ( uint64 , * pbpeering . Peering , error )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
PeeringList ( ws memdb . WatchSet , entMeta acl . EnterpriseMeta ) ( uint64 , [ ] * pbpeering . Peering , error )
2022-05-12 22:58:22 +00:00
PeeringTrustBundleRead ( ws memdb . WatchSet , q state . Query ) ( uint64 , * pbpeering . PeeringTrustBundle , error )
2022-06-15 19:36:18 +00:00
PeeringTrustBundleList ( ws memdb . WatchSet , entMeta acl . EnterpriseMeta ) ( uint64 , [ ] * pbpeering . PeeringTrustBundle , error )
2022-06-27 19:37:18 +00:00
TrustBundleListByService ( ws memdb . WatchSet , service , dc string , entMeta acl . EnterpriseMeta ) ( uint64 , [ ] * pbpeering . PeeringTrustBundle , error )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
}
2022-07-22 22:20:21 +00:00
var peeringNotEnabledErr = grpcstatus . Error ( codes . FailedPrecondition , "peering must be enabled to use this endpoint" )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
// GenerateToken implements the PeeringService RPC method to generate a
// peering token which is the initial step in establishing a peering relationship
// with other Consul clusters.
2022-07-08 17:01:13 +00:00
func ( s * Server ) GenerateToken (
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
ctx context . Context ,
req * pbpeering . GenerateTokenRequest ,
) ( * pbpeering . GenerateTokenResponse , error ) {
2022-07-22 22:20:21 +00:00
if ! s . Config . PeeringEnabled {
return nil , peeringNotEnabledErr
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
if err := s . Backend . EnterpriseCheckPartitions ( req . Partition ) ; err != nil {
return nil , grpcstatus . Error ( codes . InvalidArgument , err . Error ( ) )
}
// validate prior to forwarding to the leader, this saves a network hop
2023-01-13 20:20:28 +00:00
if err := validatePeerName ( req . PeerName ) ; err != nil {
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
return nil , fmt . Errorf ( "%s is not a valid peer name: %w" , req . PeerName , err )
}
2022-05-09 20:47:37 +00:00
if err := structs . ValidateMetaTags ( req . Meta ) ; err != nil {
return nil , fmt . Errorf ( "meta tags failed validation: %w" , err )
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
resp := & pbpeering . GenerateTokenResponse { }
2022-07-12 23:18:05 +00:00
handled , err := s . ForwardRPC ( & writeRequest , func ( conn * grpc . ClientConn ) error {
ctx := external . ForwardMetadataContext ( ctx )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
var err error
resp , err = pbpeering . NewPeeringServiceClient ( conn ) . GenerateToken ( ctx , req )
return err
} )
if handled || err != nil {
return resp , err
}
2022-09-09 21:10:48 +00:00
defer metrics . MeasureSince ( [ ] string { "peering" , "generate_token" } , time . Now ( ) )
2022-07-12 23:18:05 +00:00
var authzCtx acl . AuthorizerContext
entMeta := structs . DefaultEnterpriseMetaInPartition ( req . Partition )
2022-09-28 16:56:59 +00:00
options , err := external . QueryOptionsFromContext ( ctx )
if err != nil {
return nil , err
}
authz , err := s . Backend . ResolveTokenAndDefaultMeta ( options . Token , entMeta , & authzCtx )
2022-07-12 23:18:05 +00:00
if err != nil {
return nil , err
}
if err := authz . ToAllowAuthorizer ( ) . PeeringWriteAllowed ( & authzCtx ) ; err != nil {
return nil , err
}
2022-09-29 21:49:58 +00:00
serverName , caPEMs , err := s . Backend . GetTLSMaterials ( true )
if err != nil {
return nil , err
}
2022-08-01 14:33:18 +00:00
var (
peering * pbpeering . Peering
secretID string
)
2022-07-25 18:37:56 +00:00
// This loop ensures at most one retry in the case of a race condition.
for canRetry := true ; canRetry ; canRetry = false {
peering , err = s . getExistingPeering ( req . PeerName , entMeta . PartitionOrDefault ( ) )
if err != nil {
return nil , err
}
if peering == nil {
id , err := lib . GenerateUUID ( s . Backend . CheckPeeringUUID )
if err != nil {
return resp , err
}
peering = & pbpeering . Peering {
ID : id ,
Name : req . PeerName ,
Meta : req . Meta ,
// PartitionOrEmpty is used to avoid writing "default" in OSS.
Partition : entMeta . PartitionOrEmpty ( ) ,
}
} else {
// validate that this peer name is not being used as a dialer already
if err := validatePeer ( peering , false ) ; err != nil {
return nil , err
}
}
2022-08-01 14:33:18 +00:00
// A new establishment secret is generated on every GenerateToken request.
// This allows for rotating secrets by generating a new token for a peering and then
// using the new token to re-establish the peering.
secretID , err = s . generateNewEstablishmentSecret ( )
if err != nil {
return nil , fmt . Errorf ( "failed to generate secret for peering establishment: %w" , err )
}
writeReq := & pbpeering . PeeringWriteRequest {
2022-07-25 18:37:56 +00:00
Peering : peering ,
2022-08-08 07:41:00 +00:00
SecretsRequest : & pbpeering . SecretsWriteRequest {
PeerID : peering . ID ,
Request : & pbpeering . SecretsWriteRequest_GenerateToken {
GenerateToken : & pbpeering . SecretsWriteRequest_GenerateTokenRequest {
EstablishmentSecret : secretID ,
2022-08-02 22:20:07 +00:00
} ,
2022-08-01 14:33:18 +00:00
} ,
} ,
2022-07-25 18:37:56 +00:00
}
2022-08-01 14:33:18 +00:00
if err := s . Backend . PeeringWrite ( writeReq ) ; err != nil {
2022-07-25 18:37:56 +00:00
// There's a possible race where two servers call Generate Token at the
// same time with the same peer name for the first time. They both
// generate an ID and try to insert and only one wins. This detects the
// collision and forces the loser to discard its generated ID and use
// the one from the other server.
if strings . Contains ( err . Error ( ) , "A peering already exists with the name" ) {
// retry to fetch existing peering
continue
}
return nil , fmt . Errorf ( "failed to write peering: %w" , err )
}
// write succeeded, break loop early
break
}
2022-10-19 16:31:36 +00:00
serverAddrs , err := s . Backend . GetLocalServerAddresses ( )
if err != nil {
return nil , err
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
}
tok := structs . PeeringToken {
// Store the UUID so that we can do a global search when handling inbound streams.
2022-11-08 20:55:18 +00:00
PeerID : peering . ID ,
CA : caPEMs ,
ManualServerAddresses : req . ServerExternalAddresses ,
ServerAddresses : serverAddrs ,
ServerName : serverName ,
EstablishmentSecret : secretID ,
2022-10-05 13:10:19 +00:00
Remote : structs . PeeringTokenRemote {
Partition : req . PartitionOrDefault ( ) ,
Datacenter : s . Datacenter ,
2023-03-07 19:05:23 +00:00
Locality : s . Config . Locality ,
2022-10-05 13:10:19 +00:00
} ,
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
}
encoded , err := s . Backend . EncodeToken ( & tok )
if err != nil {
return nil , err
}
resp . PeeringToken = string ( encoded )
return resp , err
}
2022-06-10 16:10:46 +00:00
// Establish implements the PeeringService RPC method to finalize peering
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
// registration. Given a valid token output from a peer's GenerateToken endpoint,
// a peering is registered.
2022-07-08 17:01:13 +00:00
func ( s * Server ) Establish (
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
ctx context . Context ,
2022-06-10 16:10:46 +00:00
req * pbpeering . EstablishRequest ,
) ( * pbpeering . EstablishResponse , error ) {
2022-07-22 22:20:21 +00:00
if ! s . Config . PeeringEnabled {
return nil , peeringNotEnabledErr
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
// validate prior to forwarding to the leader, this saves a network hop
2023-01-13 20:20:28 +00:00
if err := validatePeerName ( req . PeerName ) ; err != nil {
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
return nil , fmt . Errorf ( "%s is not a valid peer name: %w" , req . PeerName , err )
}
tok , err := s . Backend . DecodeToken ( [ ] byte ( req . PeeringToken ) )
if err != nil {
return nil , err
}
if err := validatePeeringToken ( tok ) ; err != nil {
return nil , err
}
2022-05-09 20:47:37 +00:00
if err := structs . ValidateMetaTags ( req . Meta ) ; err != nil {
return nil , fmt . Errorf ( "meta tags failed validation: %w" , err )
}
2022-06-10 16:10:46 +00:00
resp := & pbpeering . EstablishResponse { }
2022-07-12 23:18:05 +00:00
handled , err := s . ForwardRPC ( & writeRequest , func ( conn * grpc . ClientConn ) error {
ctx := external . ForwardMetadataContext ( ctx )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
var err error
2022-06-10 16:10:46 +00:00
resp , err = pbpeering . NewPeeringServiceClient ( conn ) . Establish ( ctx , req )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
return err
} )
if handled || err != nil {
return resp , err
}
2022-06-10 16:10:46 +00:00
defer metrics . MeasureSince ( [ ] string { "peering" , "establish" } , time . Now ( ) )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
2022-07-12 23:18:05 +00:00
var authzCtx acl . AuthorizerContext
entMeta := structs . DefaultEnterpriseMetaInPartition ( req . Partition )
2022-09-28 16:56:59 +00:00
options , err := external . QueryOptionsFromContext ( ctx )
if err != nil {
return nil , err
}
authz , err := s . Backend . ResolveTokenAndDefaultMeta ( options . Token , entMeta , & authzCtx )
2022-07-12 23:18:05 +00:00
if err != nil {
return nil , err
}
if err := authz . ToAllowAuthorizer ( ) . PeeringWriteAllowed ( & authzCtx ) ; err != nil {
return nil , err
}
2022-08-01 14:33:18 +00:00
existing , err := s . getExistingPeering ( req . PeerName , entMeta . PartitionOrDefault ( ) )
2022-07-22 22:56:25 +00:00
if err != nil {
return nil , err
}
2022-10-07 18:17:11 +00:00
if err := s . validatePeeringLocality ( tok ) ; err != nil {
2022-07-26 01:00:48 +00:00
return nil , err
}
2022-07-22 22:56:25 +00:00
var id string
2022-08-26 14:27:13 +00:00
serverAddrs := tok . ServerAddresses
2022-08-01 14:33:18 +00:00
if existing == nil {
2022-07-22 22:56:25 +00:00
id , err = lib . GenerateUUID ( s . Backend . CheckPeeringUUID )
if err != nil {
return nil , err
}
2022-07-25 18:37:56 +00:00
} else {
2022-08-01 14:33:18 +00:00
id = existing . ID
2022-08-26 14:27:13 +00:00
// If there is a connected stream, assume that the existing ServerAddresses
// are up to date and do not try to overwrite them with the token's addresses.
if status , ok := s . Tracker . StreamStatus ( id ) ; ok && status . Connected {
serverAddrs = existing . PeerServerAddresses
}
2022-07-25 18:37:56 +00:00
}
// validate that this peer name is not being used as an acceptor already
2022-08-01 14:33:18 +00:00
if err := validatePeer ( existing , true ) ; err != nil {
2022-07-25 18:37:56 +00:00
return nil , err
2022-07-22 22:56:25 +00:00
}
2022-08-01 14:33:18 +00:00
peering := & pbpeering . Peering {
2022-11-08 20:55:18 +00:00
ID : id ,
Name : req . PeerName ,
PeerCAPems : tok . CA ,
ManualServerAddresses : tok . ManualServerAddresses ,
PeerServerAddresses : serverAddrs ,
PeerServerName : tok . ServerName ,
PeerID : tok . PeerID ,
Meta : req . Meta ,
2022-10-10 19:45:30 +00:00
// State is intentionally not set until after the secret exchange succeeds.
// This is to prevent a scenario where an active peering is re-established,
// the secret exchange fails, and the peering state gets stuck in "Establishing"
// while the original connection is still active.
// State: pbpeering.PeeringState_ESTABLISHING,
2022-08-01 14:33:18 +00:00
// PartitionOrEmpty is used to avoid writing "default" in OSS.
Partition : entMeta . PartitionOrEmpty ( ) ,
2022-10-05 13:10:19 +00:00
Remote : & pbpeering . RemoteInfo {
Partition : tok . Remote . Partition ,
Datacenter : tok . Remote . Datacenter ,
2023-03-10 14:36:15 +00:00
Locality : pbcommon . LocalityToProto ( tok . Remote . Locality ) ,
2022-10-05 13:10:19 +00:00
} ,
2022-08-01 14:33:18 +00:00
}
2022-10-10 19:45:30 +00:00
// Write the peering ahead of the ExchangeSecret handshake to give
// mesh gateways in the default partition an opportunity
// to update their config with an outbound route to this peer server.
//
// If the request to exchange a secret fails then the peering will continue to exist.
// We do not undo this write because this call to establish may actually be a re-establish call
// for an active peering.
writeReq := & pbpeering . PeeringWriteRequest {
Peering : peering ,
2022-08-01 14:33:18 +00:00
}
2022-10-10 19:45:30 +00:00
if err := s . Backend . PeeringWrite ( writeReq ) ; err != nil {
return nil , fmt . Errorf ( "failed to write peering: %w" , err )
2022-08-01 14:33:18 +00:00
}
2022-10-10 19:45:30 +00:00
exchangeResp , dialErrors := s . exchangeSecret ( ctx , peering , tok . EstablishmentSecret )
2022-08-01 14:33:18 +00:00
if exchangeResp == nil {
return nil , dialErrors
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
}
2022-10-10 19:45:30 +00:00
peering . State = pbpeering . PeeringState_ESTABLISHING
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
2022-08-08 07:41:00 +00:00
// As soon as a peering is written with a non-empty list of ServerAddresses
// and an active stream secret, a leader routine will see the peering and
// attempt to establish a peering stream with the remote peer.
2022-10-10 19:45:30 +00:00
writeReq = & pbpeering . PeeringWriteRequest {
2022-08-01 14:33:18 +00:00
Peering : peering ,
2022-08-08 07:41:00 +00:00
SecretsRequest : & pbpeering . SecretsWriteRequest {
PeerID : peering . ID ,
Request : & pbpeering . SecretsWriteRequest_Establish {
Establish : & pbpeering . SecretsWriteRequest_EstablishRequest {
ActiveStreamSecret : exchangeResp . StreamSecret ,
2022-08-02 22:20:07 +00:00
} ,
2022-08-01 14:33:18 +00:00
} ,
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
} ,
}
2022-07-25 18:37:56 +00:00
if err := s . Backend . PeeringWrite ( writeReq ) ; err != nil {
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
return nil , fmt . Errorf ( "failed to write peering: %w" , err )
}
return resp , nil
}
2022-10-07 18:17:11 +00:00
// validatePeeringLocality makes sure that we don't create a peering in the same cluster it was generated.
// If the ServerName of the PeeringToken overlaps with our own, we do not accept it.
func ( s * Server ) validatePeeringLocality ( token * structs . PeeringToken ) error {
2022-09-29 21:49:58 +00:00
serverName , _ , err := s . Backend . GetTLSMaterials ( false )
2022-09-29 03:27:11 +00:00
if err != nil {
return fmt . Errorf ( "failed to fetch TLS materials: %w" , err )
}
2022-10-07 18:17:11 +00:00
if serverName == token . ServerName {
2022-10-13 18:27:21 +00:00
return fmt . Errorf (
"cannot create a peering within the same cluster %q. Refer to the `exported-services` documentation if you want to export between partitions without peering" ,
serverName )
2022-09-09 21:09:32 +00:00
}
2022-07-26 01:00:48 +00:00
return nil
}
2022-10-10 19:45:30 +00:00
// exchangeSecret will continuously attempt to exchange the given establishment secret with the peer, up to a timeout.
// This function will attempt to dial through mesh gateways if the local DC is configured to peer through gateways,
// but will fall back to server addresses if not.
func ( s * Server ) exchangeSecret ( ctx context . Context , peering * pbpeering . Peering , establishmentSecret string ) ( * pbpeerstream . ExchangeSecretResponse , error ) {
req := pbpeerstream . ExchangeSecretRequest {
PeerID : peering . PeerID ,
EstablishmentSecret : establishmentSecret ,
}
2022-08-01 14:33:18 +00:00
2022-10-10 19:45:30 +00:00
tlsOption , err := peering . TLSDialOption ( )
2022-08-01 14:33:18 +00:00
if err != nil {
2022-10-10 19:45:30 +00:00
return nil , fmt . Errorf ( "failed to build TLS dial option from peering: %w" , err )
}
2022-11-10 18:54:00 +00:00
allAddrs , gatewayAddrs , err := s . Backend . GetDialAddresses ( s . Logger , nil , peering . ID )
2022-10-10 19:45:30 +00:00
if err != nil {
return nil , fmt . Errorf ( "failed to get addresses to dial peer: %w" , err )
2022-08-01 14:33:18 +00:00
}
2022-11-10 18:54:00 +00:00
if gatewayAddrs != nil {
// If we are dialing through local gateways we sleep before issuing the first request.
// This gives the local gateways some time to configure a route to the peer servers.
time . Sleep ( meshGatewayWait )
// Exclusively try
resp , _ := retryExchange ( ctx , & req , gatewayAddrs , tlsOption )
if resp != nil {
return resp , nil
}
}
return retryExchange ( ctx , & req , allAddrs , tlsOption )
}
// retryExchange attempts a secret exchange in a retry loop, taking a new address from the ring buffer on each iteration
func retryExchange ( ctx context . Context , req * pbpeerstream . ExchangeSecretRequest , ringBuf * ring . Ring , tlsOption grpc . DialOption ) ( * pbpeerstream . ExchangeSecretResponse , error ) {
2022-10-10 19:45:30 +00:00
var (
resp * pbpeerstream . ExchangeSecretResponse
dialErrors error
)
retryWait := 150 * time . Millisecond
jitter := retry . NewJitter ( 25 )
retryCtx , cancel := context . WithTimeout ( ctx , establishmentTimeout )
defer cancel ( )
for retryCtx . Err ( ) == nil {
addr := ringBuf . Value . ( string )
dialCtx , cancel := context . WithTimeout ( ctx , 2 * time . Second )
defer cancel ( )
conn , err := grpc . DialContext ( dialCtx , addr ,
tlsOption ,
)
if err != nil {
return nil , fmt . Errorf ( "failed to dial peer: %w" , err )
}
defer conn . Close ( )
client := pbpeerstream . NewPeerStreamServiceClient ( conn )
2022-11-10 18:54:00 +00:00
resp , err = client . ExchangeSecret ( ctx , req )
2022-10-10 19:45:30 +00:00
// If we got a permission denied error that means out establishment secret is invalid, so we do not retry.
grpcErr , ok := grpcstatus . FromError ( err )
if ok && grpcErr . Code ( ) == codes . PermissionDenied {
2022-10-20 23:10:03 +00:00
return nil , grpcstatus . Errorf ( codes . PermissionDenied , "a new peering token must be generated: %s" , grpcErr . Message ( ) )
2022-10-10 19:45:30 +00:00
}
if err != nil {
dialErrors = multierror . Append ( dialErrors , fmt . Errorf ( "failed to exchange peering secret through address %q: %w" , addr , err ) )
}
if resp != nil {
// Got a valid response. We're done.
break
}
time . Sleep ( jitter ( retryWait ) )
// Cycle to the next possible address.
ringBuf = ringBuf . Next ( )
}
return resp , dialErrors
2022-08-01 14:33:18 +00:00
}
2023-05-23 21:29:10 +00:00
// PeeringRead returns the peering of the requested name and partition (enterprise only).
// Note that for the purposes of the blocking query, changes are only observed as part of the
// storage Index, which does not include the hydrated state from reconcilePeering, including
// the Active state and the count of imported/exported services.
2022-07-08 17:01:13 +00:00
func ( s * Server ) PeeringRead ( ctx context . Context , req * pbpeering . PeeringReadRequest ) ( * pbpeering . PeeringReadResponse , error ) {
2022-07-22 22:20:21 +00:00
if ! s . Config . PeeringEnabled {
return nil , peeringNotEnabledErr
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
if err := s . Backend . EnterpriseCheckPartitions ( req . Partition ) ; err != nil {
return nil , grpcstatus . Error ( codes . InvalidArgument , err . Error ( ) )
}
2023-05-23 21:29:10 +00:00
options , err := external . QueryOptionsFromContext ( ctx )
if err != nil {
return nil , err
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
var resp * pbpeering . PeeringReadResponse
2023-05-23 21:29:10 +00:00
handled , err := s . ForwardRPC ( & readRequest { options , emptyDCSpecificRequest } , func ( conn * grpc . ClientConn ) error {
2022-07-12 23:18:05 +00:00
ctx := external . ForwardMetadataContext ( ctx )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
var err error
resp , err = pbpeering . NewPeeringServiceClient ( conn ) . PeeringRead ( ctx , req )
return err
} )
if handled || err != nil {
return resp , err
}
defer metrics . MeasureSince ( [ ] string { "peering" , "read" } , time . Now ( ) )
2022-07-12 23:18:05 +00:00
var authzCtx acl . AuthorizerContext
entMeta := structs . DefaultEnterpriseMetaInPartition ( req . Partition )
2023-05-23 21:29:10 +00:00
2022-09-28 16:56:59 +00:00
authz , err := s . Backend . ResolveTokenAndDefaultMeta ( options . Token , entMeta , & authzCtx )
2022-07-12 23:18:05 +00:00
if err != nil {
return nil , err
}
if err := authz . ToAllowAuthorizer ( ) . PeeringReadAllowed ( & authzCtx ) ; err != nil {
return nil , err
}
2023-05-23 21:29:10 +00:00
res := & pbpeering . PeeringReadResponse { }
meta := structs . QueryMeta { }
err = blockingquery . Query ( s . FSMServer , & options , & meta , func ( ws memdb . WatchSet , store * state . Store ) error {
q := state . Query {
Value : strings . ToLower ( req . Name ) ,
EnterpriseMeta : * entMeta ,
}
idx , peering , err := store . PeeringRead ( ws , q )
if err != nil {
return err
}
meta . SetIndex ( idx )
if peering == nil {
return blockingquery . ErrNotFound
}
res . Peering = s . reconcilePeering ( peering )
return nil
} )
if err != nil {
return nil , fmt . Errorf ( "error executing peering read blocking query: %w" , err )
2022-07-12 23:18:05 +00:00
}
2023-05-23 21:29:10 +00:00
header , err := external . GRPCMetadataFromQueryMeta ( meta )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
if err != nil {
2023-05-23 21:29:10 +00:00
return nil , fmt . Errorf ( "could not convert query metadata to gRPC header" )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
}
2023-05-23 21:29:10 +00:00
if err := grpc . SendHeader ( ctx , header ) ; err != nil {
return nil , fmt . Errorf ( "could not send gRPC header" )
2022-06-29 16:43:50 +00:00
}
2022-07-15 17:20:43 +00:00
2023-05-23 21:29:10 +00:00
return res , nil
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
}
2023-05-23 21:29:10 +00:00
// PeeringList returns the list of peerings in the requested partition(s) (enterprise only).
// Note that for the purposes of the blocking query, changes are only observed as part of the
// storage Index, which does not include the hydrated state from reconcilePeering, including
// the Active state and the count of imported/exported services.
2022-07-08 17:01:13 +00:00
func ( s * Server ) PeeringList ( ctx context . Context , req * pbpeering . PeeringListRequest ) ( * pbpeering . PeeringListResponse , error ) {
2022-07-22 22:20:21 +00:00
if ! s . Config . PeeringEnabled {
return nil , peeringNotEnabledErr
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
if err := s . Backend . EnterpriseCheckPartitions ( req . Partition ) ; err != nil {
return nil , grpcstatus . Error ( codes . InvalidArgument , err . Error ( ) )
}
2023-05-23 21:29:10 +00:00
options , err := external . QueryOptionsFromContext ( ctx )
if err != nil {
return nil , err
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
var resp * pbpeering . PeeringListResponse
2023-05-23 21:29:10 +00:00
handled , err := s . ForwardRPC ( & readRequest { options , emptyDCSpecificRequest } , func ( conn * grpc . ClientConn ) error {
2022-07-12 23:18:05 +00:00
ctx := external . ForwardMetadataContext ( ctx )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
var err error
resp , err = pbpeering . NewPeeringServiceClient ( conn ) . PeeringList ( ctx , req )
return err
} )
if handled || err != nil {
return resp , err
}
2022-07-12 23:18:05 +00:00
var authzCtx acl . AuthorizerContext
entMeta := structs . DefaultEnterpriseMetaInPartition ( req . Partition )
2022-09-28 16:56:59 +00:00
authz , err := s . Backend . ResolveTokenAndDefaultMeta ( options . Token , entMeta , & authzCtx )
2022-07-12 23:18:05 +00:00
if err != nil {
return nil , err
}
if err := authz . ToAllowAuthorizer ( ) . PeeringReadAllowed ( & authzCtx ) ; err != nil {
return nil , err
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
defer metrics . MeasureSince ( [ ] string { "peering" , "list" } , time . Now ( ) )
2023-05-23 21:29:10 +00:00
res := & pbpeering . PeeringListResponse { }
meta := structs . QueryMeta { }
err = blockingquery . Query ( s . FSMServer , & options , & meta , func ( ws memdb . WatchSet , store * state . Store ) error {
idx , peerings , err := store . PeeringList ( ws , * entMeta )
if err != nil {
return err
}
// reconcile the actual peering state; need to copy over the ds for peering
var cPeerings [ ] * pbpeering . Peering
for _ , p := range peerings {
cp := s . reconcilePeering ( p )
cPeerings = append ( cPeerings , cp )
}
res . Peerings = cPeerings
meta . SetIndex ( idx )
res . OBSOLETE_Index = idx // Compatibility with 1.14 API, deprecate in future release
return nil
} )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
if err != nil {
2023-05-23 21:29:10 +00:00
return nil , fmt . Errorf ( "error executing peering list blocking query: %w" , err )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
}
2022-06-29 16:43:50 +00:00
2023-05-23 21:29:10 +00:00
header , err := external . GRPCMetadataFromQueryMeta ( meta )
if err != nil {
return nil , fmt . Errorf ( "could not convert query metadata to gRPC header" )
}
if err := grpc . SendHeader ( ctx , header ) ; err != nil {
return nil , fmt . Errorf ( "could not send gRPC header" )
2022-06-29 16:43:50 +00:00
}
2022-07-19 18:43:29 +00:00
2023-05-23 21:29:10 +00:00
return res , nil
2022-06-29 16:43:50 +00:00
}
2022-07-19 18:43:29 +00:00
// TODO(peering): Get rid of this func when we stop using the stream tracker for imported/ exported services and the peering state
// reconcilePeering enriches the peering with the following information:
// -- PeeringState.Active if the peering is active
// -- ImportedServicesCount and ExportedServicesCount
// NOTE: we return a new peering with this additional data
func ( s * Server ) reconcilePeering ( peering * pbpeering . Peering ) * pbpeering . Peering {
streamState , found := s . Tracker . StreamStatus ( peering . ID )
if ! found {
2022-09-23 22:44:26 +00:00
// TODO(peering): this may be noise on non-leaders
2022-07-19 18:43:29 +00:00
s . Logger . Warn ( "did not find peer in stream tracker; cannot populate imported and" +
" exported services count or reconcile peering state" , "peerID" , peering . ID )
2022-09-23 22:44:26 +00:00
peering . StreamStatus = & pbpeering . StreamStatus { }
2022-07-19 18:43:29 +00:00
return peering
} else {
cp := copyPeering ( peering )
2022-06-29 16:43:50 +00:00
2022-07-19 18:43:29 +00:00
// reconcile pbpeering.PeeringState_Active
if streamState . Connected {
cp . State = pbpeering . PeeringState_ACTIVE
2022-07-25 21:27:53 +00:00
} else if streamState . DisconnectErrorMessage != "" {
cp . State = pbpeering . PeeringState_FAILING
2022-07-19 18:43:29 +00:00
}
2022-06-29 16:43:50 +00:00
2022-11-03 18:51:22 +00:00
latest := func ( tt ... * time . Time ) * time . Time {
2022-09-23 21:51:41 +00:00
latest := time . Time { }
for _ , t := range tt {
2022-11-03 18:51:22 +00:00
if t == nil {
continue
}
2022-09-23 21:51:41 +00:00
if t . After ( latest ) {
2022-11-03 18:51:22 +00:00
latest = * t
2022-09-23 21:51:41 +00:00
}
}
2022-11-03 18:51:22 +00:00
return & latest
2022-09-23 21:51:41 +00:00
}
lastRecv := latest ( streamState . LastRecvHeartbeat , streamState . LastRecvError , streamState . LastRecvResourceSuccess )
lastSend := latest ( streamState . LastSendError , streamState . LastSendSuccess )
cp . StreamStatus = & pbpeering . StreamStatus {
ImportedServices : streamState . ImportedServices ,
ExportedServices : streamState . ExportedServices ,
2022-11-03 18:51:22 +00:00
LastHeartbeat : pbpeering . TimePtrToProto ( streamState . LastRecvHeartbeat ) ,
LastReceive : pbpeering . TimePtrToProto ( lastRecv ) ,
LastSend : pbpeering . TimePtrToProto ( lastSend ) ,
2022-09-23 21:51:41 +00:00
}
2022-07-19 18:43:29 +00:00
return cp
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
}
// TODO(peering): As of writing, this method is only used in tests to set up Peerings in the state store.
// Consider removing if we can find another way to populate state store in peering_endpoint_test.go
2022-07-08 17:01:13 +00:00
func ( s * Server ) PeeringWrite ( ctx context . Context , req * pbpeering . PeeringWriteRequest ) ( * pbpeering . PeeringWriteResponse , error ) {
2022-07-22 22:20:21 +00:00
if ! s . Config . PeeringEnabled {
return nil , peeringNotEnabledErr
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
if err := s . Backend . EnterpriseCheckPartitions ( req . Peering . Partition ) ; err != nil {
return nil , grpcstatus . Error ( codes . InvalidArgument , err . Error ( ) )
}
var resp * pbpeering . PeeringWriteResponse
2022-07-12 23:18:05 +00:00
handled , err := s . ForwardRPC ( & writeRequest , func ( conn * grpc . ClientConn ) error {
ctx := external . ForwardMetadataContext ( ctx )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
var err error
resp , err = pbpeering . NewPeeringServiceClient ( conn ) . PeeringWrite ( ctx , req )
return err
} )
if handled || err != nil {
return resp , err
}
defer metrics . MeasureSince ( [ ] string { "peering" , "write" } , time . Now ( ) )
2022-07-12 23:18:05 +00:00
var authzCtx acl . AuthorizerContext
entMeta := structs . DefaultEnterpriseMetaInPartition ( req . Peering . Partition )
2022-09-28 16:56:59 +00:00
options , err := external . QueryOptionsFromContext ( ctx )
if err != nil {
return nil , err
}
authz , err := s . Backend . ResolveTokenAndDefaultMeta ( options . Token , entMeta , & authzCtx )
2022-07-12 23:18:05 +00:00
if err != nil {
return nil , err
}
if err := authz . ToAllowAuthorizer ( ) . PeeringWriteAllowed ( & authzCtx ) ; err != nil {
return nil , err
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
2022-06-21 18:04:08 +00:00
if req . Peering == nil {
return nil , fmt . Errorf ( "missing required peering body" )
}
2022-07-25 18:37:56 +00:00
var id string
peering , err := s . getExistingPeering ( req . Peering . Name , entMeta . PartitionOrDefault ( ) )
2022-06-21 18:04:08 +00:00
if err != nil {
return nil , err
}
2022-07-25 18:37:56 +00:00
if peering == nil {
id , err = lib . GenerateUUID ( s . Backend . CheckPeeringUUID )
if err != nil {
return nil , err
}
} else {
id = peering . ID
}
2022-06-21 18:04:08 +00:00
req . Peering . ID = id
2022-07-08 17:01:13 +00:00
err = s . Backend . PeeringWrite ( req )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
if err != nil {
return nil , err
}
return & pbpeering . PeeringWriteResponse { } , nil
}
2022-07-08 17:01:13 +00:00
func ( s * Server ) PeeringDelete ( ctx context . Context , req * pbpeering . PeeringDeleteRequest ) ( * pbpeering . PeeringDeleteResponse , error ) {
2022-07-22 22:20:21 +00:00
if ! s . Config . PeeringEnabled {
return nil , peeringNotEnabledErr
}
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
if err := s . Backend . EnterpriseCheckPartitions ( req . Partition ) ; err != nil {
return nil , grpcstatus . Error ( codes . InvalidArgument , err . Error ( ) )
}
var resp * pbpeering . PeeringDeleteResponse
2022-07-12 23:18:05 +00:00
handled , err := s . ForwardRPC ( & writeRequest , func ( conn * grpc . ClientConn ) error {
ctx := external . ForwardMetadataContext ( ctx )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
var err error
resp , err = pbpeering . NewPeeringServiceClient ( conn ) . PeeringDelete ( ctx , req )
return err
} )
if handled || err != nil {
return resp , err
}
defer metrics . MeasureSince ( [ ] string { "peering" , "delete" } , time . Now ( ) )
2022-07-12 23:18:05 +00:00
var authzCtx acl . AuthorizerContext
entMeta := structs . DefaultEnterpriseMetaInPartition ( req . Partition )
2022-09-28 16:56:59 +00:00
options , err := external . QueryOptionsFromContext ( ctx )
if err != nil {
return nil , err
}
authz , err := s . Backend . ResolveTokenAndDefaultMeta ( options . Token , entMeta , & authzCtx )
2022-07-12 23:18:05 +00:00
if err != nil {
return nil , err
}
if err := authz . ToAllowAuthorizer ( ) . PeeringWriteAllowed ( & authzCtx ) ; err != nil {
return nil , err
}
2022-06-08 22:53:32 +00:00
q := state . Query {
Value : strings . ToLower ( req . Name ) ,
2022-07-12 23:18:05 +00:00
EnterpriseMeta : * entMeta ,
2022-06-08 22:53:32 +00:00
}
_ , existing , err := s . Backend . Store ( ) . PeeringRead ( nil , q )
if err != nil {
return nil , err
}
2022-08-26 16:52:47 +00:00
if existing == nil || existing . State == pbpeering . PeeringState_DELETING {
2022-06-08 22:53:32 +00:00
// Return early when the Peering doesn't exist or is already marked for deletion.
// We don't return nil because the pb will fail to marshal.
return & pbpeering . PeeringDeleteResponse { } , nil
}
2022-08-26 16:52:47 +00:00
2022-06-08 22:53:32 +00:00
// We are using a write request due to needing to perform a deferred deletion.
// The peering gets marked for deletion by setting the DeletedAt field,
// and a leader routine will handle deleting the peering.
writeReq := & pbpeering . PeeringWriteRequest {
Peering : & pbpeering . Peering {
// We only need to include the name and partition for the peering to be identified.
// All other data associated with the peering can be discarded because once marked
// for deletion the peering is effectively gone.
2022-11-08 20:55:18 +00:00
ID : existing . ID ,
Name : req . Name ,
State : pbpeering . PeeringState_DELETING ,
ManualServerAddresses : existing . ManualServerAddresses ,
PeerServerAddresses : existing . PeerServerAddresses ,
2023-01-11 14:39:10 +00:00
DeletedAt : timestamppb . New ( time . Now ( ) . UTC ( ) ) ,
2022-07-12 23:18:05 +00:00
// PartitionOrEmpty is used to avoid writing "default" in OSS.
Partition : entMeta . PartitionOrEmpty ( ) ,
2022-06-08 22:53:32 +00:00
} ,
}
2022-07-08 17:01:13 +00:00
err = s . Backend . PeeringWrite ( writeReq )
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
if err != nil {
return nil , err
}
return & pbpeering . PeeringDeleteResponse { } , nil
}
2022-07-08 17:01:13 +00:00
func ( s * Server ) TrustBundleRead ( ctx context . Context , req * pbpeering . TrustBundleReadRequest ) ( * pbpeering . TrustBundleReadResponse , error ) {
2022-07-22 22:20:21 +00:00
if ! s . Config . PeeringEnabled {
return nil , peeringNotEnabledErr
}
2022-05-31 15:54:40 +00:00
if err := s . Backend . EnterpriseCheckPartitions ( req . Partition ) ; err != nil {
return nil , grpcstatus . Error ( codes . InvalidArgument , err . Error ( ) )
}
2022-09-28 16:56:59 +00:00
options , err := external . QueryOptionsFromContext ( ctx )
if err != nil {
return nil , err
}
2022-05-31 15:54:40 +00:00
var resp * pbpeering . TrustBundleReadResponse
2023-05-23 21:29:10 +00:00
handled , err := s . ForwardRPC ( & readRequest { options , emptyDCSpecificRequest } , func ( conn * grpc . ClientConn ) error {
2022-07-12 23:18:05 +00:00
ctx := external . ForwardMetadataContext ( ctx )
2022-05-31 15:54:40 +00:00
var err error
resp , err = pbpeering . NewPeeringServiceClient ( conn ) . TrustBundleRead ( ctx , req )
return err
} )
if handled || err != nil {
return resp , err
}
defer metrics . MeasureSince ( [ ] string { "peering" , "trust_bundle_read" } , time . Now ( ) )
2023-03-14 17:24:33 +00:00
// Having the ability to write a service in ANY (at least one) namespace should be
// sufficient for reading the trust bundle, which is why we use a wildcard.
entMeta := acl . NewEnterpriseMetaWithPartition ( req . Partition , acl . WildcardName )
entMeta . Normalize ( )
2022-07-12 23:18:05 +00:00
var authzCtx acl . AuthorizerContext
2023-03-14 17:24:33 +00:00
authz , err := s . Backend . ResolveTokenAndDefaultMeta ( options . Token , & entMeta , & authzCtx )
2022-07-12 23:18:05 +00:00
if err != nil {
return nil , err
}
if err := authz . ToAllowAuthorizer ( ) . ServiceWriteAnyAllowed ( & authzCtx ) ; err != nil {
return nil , err
}
2022-05-31 15:54:40 +00:00
2023-05-23 21:29:10 +00:00
res := & pbpeering . TrustBundleReadResponse { }
meta := structs . QueryMeta { }
err = blockingquery . Query ( s . FSMServer , & options , & meta , func ( ws memdb . WatchSet , store * state . Store ) error {
idx , trustBundle , err := store . PeeringTrustBundleRead ( ws , state . Query {
Value : req . Name ,
EnterpriseMeta : entMeta ,
} )
if err != nil {
return fmt . Errorf ( "failed to read trust bundle for peer %s: %w" , req . Name , err )
}
meta . SetIndex ( idx )
if trustBundle == nil {
return blockingquery . ErrNotFound
}
res . Bundle = trustBundle
res . OBSOLETE_Index = idx // Compatibility with 1.14 API, deprecate in future release
return nil
2022-05-31 15:54:40 +00:00
} )
if err != nil {
2023-05-23 21:29:10 +00:00
return nil , fmt . Errorf ( "error executing trust bundle read blocking query: %w" , err )
}
header , err := external . GRPCMetadataFromQueryMeta ( meta )
if err != nil {
return nil , fmt . Errorf ( "could not convert query metadata to gRPC header" )
}
if err := grpc . SendHeader ( ctx , header ) ; err != nil {
return nil , fmt . Errorf ( "could not send gRPC header" )
2022-05-31 15:54:40 +00:00
}
2023-05-23 21:29:10 +00:00
return res , nil
2022-05-31 15:54:40 +00:00
}
2022-06-15 19:36:18 +00:00
// TODO(peering): rename rpc & request/response to drop the "service" part
2022-07-08 17:01:13 +00:00
func ( s * Server ) TrustBundleListByService ( ctx context . Context , req * pbpeering . TrustBundleListByServiceRequest ) ( * pbpeering . TrustBundleListByServiceResponse , error ) {
2022-07-22 22:20:21 +00:00
if ! s . Config . PeeringEnabled {
return nil , peeringNotEnabledErr
}
2022-05-12 22:58:22 +00:00
if err := s . Backend . EnterpriseCheckPartitions ( req . Partition ) ; err != nil {
return nil , grpcstatus . Error ( codes . InvalidArgument , err . Error ( ) )
}
2022-06-08 16:55:18 +00:00
if err := s . Backend . EnterpriseCheckNamespaces ( req . Namespace ) ; err != nil {
return nil , grpcstatus . Error ( codes . InvalidArgument , err . Error ( ) )
}
2022-07-12 23:18:05 +00:00
if req . ServiceName == "" {
return nil , errors . New ( "missing service name" )
}
2022-05-12 22:58:22 +00:00
2023-05-23 21:29:10 +00:00
options , err := external . QueryOptionsFromContext ( ctx )
if err != nil {
return nil , err
}
2022-05-12 22:58:22 +00:00
var resp * pbpeering . TrustBundleListByServiceResponse
2023-05-23 21:29:10 +00:00
handled , err := s . ForwardRPC ( & readRequest { options , emptyDCSpecificRequest } , func ( conn * grpc . ClientConn ) error {
2022-07-12 23:18:05 +00:00
ctx := external . ForwardMetadataContext ( ctx )
2022-05-12 22:58:22 +00:00
var err error
resp , err = pbpeering . NewPeeringServiceClient ( conn ) . TrustBundleListByService ( ctx , req )
return err
} )
if handled || err != nil {
return resp , err
}
defer metrics . MeasureSince ( [ ] string { "peering" , "trust_bundle_list_by_service" } , time . Now ( ) )
2022-07-12 23:18:05 +00:00
var authzCtx acl . AuthorizerContext
2022-05-23 23:57:42 +00:00
entMeta := acl . NewEnterpriseMetaWithPartition ( req . Partition , req . Namespace )
2022-09-28 16:56:59 +00:00
authz , err := s . Backend . ResolveTokenAndDefaultMeta ( options . Token , & entMeta , & authzCtx )
2022-07-12 23:18:05 +00:00
if err != nil {
return nil , err
}
if err := authz . ToAllowAuthorizer ( ) . ServiceWriteAllowed ( req . ServiceName , & authzCtx ) ; err != nil {
return nil , err
}
2022-06-15 19:36:18 +00:00
2023-05-23 21:29:10 +00:00
res := & pbpeering . TrustBundleListByServiceResponse { }
meta := structs . QueryMeta { }
err = blockingquery . Query ( s . FSMServer , & options , & meta , func ( ws memdb . WatchSet , store * state . Store ) error {
var (
idx uint64
bundles [ ] * pbpeering . PeeringTrustBundle
)
switch {
case req . Kind == string ( structs . ServiceKindMeshGateway ) :
idx , bundles , err = store . PeeringTrustBundleList ( ws , entMeta )
case req . ServiceName != "" :
idx , bundles , err = store . TrustBundleListByService ( ws , req . ServiceName , s . Datacenter , entMeta )
case req . Kind != "" :
return grpcstatus . Error ( codes . InvalidArgument , "kind must be mesh-gateway if set" )
default :
return grpcstatus . Error ( codes . InvalidArgument , "one of service or kind is required" )
}
if err != nil {
return fmt . Errorf ( "error listing trust bundles from store: %w" , err )
}
res . Bundles = bundles
meta . SetIndex ( idx )
res . OBSOLETE_Index = idx // Compatibility with 1.14 API, deprecate in future release
2022-06-15 19:36:18 +00:00
2023-05-23 21:29:10 +00:00
return nil
} )
if err != nil {
return nil , fmt . Errorf ( "error executing trust bundle list blocking query: %w" , err )
2022-06-15 19:36:18 +00:00
}
2023-05-23 21:29:10 +00:00
header , err := external . GRPCMetadataFromQueryMeta ( meta )
2022-05-12 22:58:22 +00:00
if err != nil {
2023-05-23 21:29:10 +00:00
return nil , fmt . Errorf ( "could not convert query metadata to gRPC header" )
2022-05-12 22:58:22 +00:00
}
2023-05-23 21:29:10 +00:00
if err := grpc . SendHeader ( ctx , header ) ; err != nil {
return nil , fmt . Errorf ( "could not send gRPC header" )
}
return res , nil
2022-05-12 22:58:22 +00:00
}
2022-07-22 22:56:25 +00:00
func ( s * Server ) getExistingPeering ( peerName , partition string ) ( * pbpeering . Peering , error ) {
q := state . Query {
Value : strings . ToLower ( peerName ) ,
EnterpriseMeta : * structs . NodeEnterpriseMetaInPartition ( partition ) ,
}
_ , peering , err := s . Backend . Store ( ) . PeeringRead ( nil , q )
if err != nil {
return nil , err
}
return peering , nil
}
2022-08-01 14:33:18 +00:00
func ( s * Server ) generateNewEstablishmentSecret ( ) ( string , error ) {
id , err := lib . GenerateUUID ( s . Backend . ValidateProposedPeeringSecret )
if err != nil {
return "" , err
}
return id , nil
}
2022-07-22 22:56:25 +00:00
// validatePeer enforces the following rule for an existing peering:
// - if a peering already exists, it can only be used as an acceptor or dialer
//
// We define a DIALER as a peering that has server addresses (or a peering that is created via the Establish endpoint)
// Conversely, we define an ACCEPTOR as a peering that is created via the GenerateToken endpoint
2022-07-25 18:37:56 +00:00
func validatePeer ( peering * pbpeering . Peering , shouldDial bool ) error {
if peering != nil && peering . ShouldDial ( ) != shouldDial {
if shouldDial {
2022-07-22 22:56:25 +00:00
return fmt . Errorf ( "cannot create peering with name: %q; there is an existing peering expecting to be dialed" , peering . Name )
} else {
return fmt . Errorf ( "cannot create peering with name: %q; there is already an established peering" , peering . Name )
}
}
return nil
}
2022-07-19 18:43:29 +00:00
func copyPeering ( p * pbpeering . Peering ) * pbpeering . Peering {
var copyP pbpeering . Peering
proto . Merge ( & copyP , p )
return & copyP
2022-06-29 16:43:50 +00:00
}