2020-09-08 19:22:35 +00:00
|
|
|
package subscribe
|
|
|
|
|
|
|
|
import (
|
2020-09-08 21:31:47 +00:00
|
|
|
"errors"
|
|
|
|
|
2020-09-28 22:52:31 +00:00
|
|
|
"github.com/hashicorp/go-hclog"
|
2020-09-08 21:31:47 +00:00
|
|
|
"google.golang.org/grpc"
|
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
"google.golang.org/grpc/status"
|
|
|
|
|
|
|
|
"github.com/hashicorp/consul/acl"
|
2020-09-25 23:40:10 +00:00
|
|
|
"github.com/hashicorp/consul/agent/consul/state"
|
2020-09-08 21:31:47 +00:00
|
|
|
"github.com/hashicorp/consul/agent/consul/stream"
|
2020-10-21 20:08:33 +00:00
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
2020-09-08 21:31:47 +00:00
|
|
|
"github.com/hashicorp/consul/proto/pbsubscribe"
|
2020-09-08 19:22:35 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Server implements a StateChangeSubscriptionServer for accepting SubscribeRequests,
|
|
|
|
// and sending events to the subscription topic.
|
|
|
|
type Server struct {
|
2020-09-08 21:31:47 +00:00
|
|
|
Backend Backend
|
|
|
|
Logger Logger
|
2020-09-08 19:22:35 +00:00
|
|
|
}
|
|
|
|
|
2020-09-28 22:52:31 +00:00
|
|
|
func NewServer(backend Backend, logger Logger) *Server {
|
|
|
|
return &Server{Backend: backend, Logger: logger}
|
|
|
|
}
|
|
|
|
|
2020-09-08 21:31:47 +00:00
|
|
|
type Logger interface {
|
|
|
|
Trace(msg string, args ...interface{})
|
2020-09-28 22:52:31 +00:00
|
|
|
With(args ...interface{}) hclog.Logger
|
2020-09-08 21:31:47 +00:00
|
|
|
}
|
2020-09-08 19:22:35 +00:00
|
|
|
|
2020-09-08 21:31:47 +00:00
|
|
|
var _ pbsubscribe.StateChangeSubscriptionServer = (*Server)(nil)
|
|
|
|
|
|
|
|
type Backend interface {
|
2022-04-05 21:10:06 +00:00
|
|
|
ResolveTokenAndDefaultMeta(token string, entMeta *acl.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error)
|
2021-09-22 18:14:26 +00:00
|
|
|
Forward(info structs.RPCInfo, f func(*grpc.ClientConn) error) (handled bool, err error)
|
2020-09-08 21:31:47 +00:00
|
|
|
Subscribe(req *stream.SubscribeRequest) (*stream.Subscription, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Server) Subscribe(req *pbsubscribe.SubscribeRequest, serverStream pbsubscribe.StateChangeSubscription_SubscribeServer) error {
|
2020-10-21 20:08:33 +00:00
|
|
|
logger := newLoggerForRequest(h.Logger, req)
|
2021-09-22 18:14:26 +00:00
|
|
|
handled, err := h.Backend.Forward(req, forwardToDC(req, serverStream, logger))
|
2020-09-08 21:31:47 +00:00
|
|
|
if handled || err != nil {
|
|
|
|
return err
|
2020-09-08 19:22:35 +00:00
|
|
|
}
|
|
|
|
|
2020-09-28 22:52:31 +00:00
|
|
|
logger.Trace("new subscription")
|
|
|
|
defer logger.Trace("subscription closed")
|
2020-09-08 19:22:35 +00:00
|
|
|
|
2022-04-05 21:10:06 +00:00
|
|
|
entMeta := acl.NewEnterpriseMetaWithPartition(req.Partition, req.Namespace)
|
2020-10-21 20:08:33 +00:00
|
|
|
authz, err := h.Backend.ResolveTokenAndDefaultMeta(req.Token, &entMeta, nil)
|
2020-09-08 19:22:35 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-01-28 12:27:00 +00:00
|
|
|
if req.Key == "" {
|
|
|
|
return status.Error(codes.InvalidArgument, "Key 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
|
|
|
sub, err := h.Backend.Subscribe(state.PBToStreamSubscribeRequest(req, entMeta))
|
2020-09-08 19:22:35 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-09-08 21:31:47 +00:00
|
|
|
defer sub.Unsubscribe()
|
2020-09-08 19:22:35 +00:00
|
|
|
|
2020-09-08 21:31:47 +00:00
|
|
|
ctx := serverStream.Context()
|
2020-09-28 22:52:31 +00:00
|
|
|
elog := &eventLogger{logger: logger}
|
2020-09-08 19:22:35 +00:00
|
|
|
for {
|
2020-10-05 16:38:38 +00:00
|
|
|
event, err := sub.Next(ctx)
|
2020-09-08 21:31:47 +00:00
|
|
|
switch {
|
2020-10-15 22:06:04 +00:00
|
|
|
case errors.Is(err, stream.ErrSubForceClosed):
|
2020-09-28 22:52:31 +00:00
|
|
|
logger.Trace("subscription reset by server")
|
2020-09-08 21:31:47 +00:00
|
|
|
return status.Error(codes.Aborted, err.Error())
|
|
|
|
case err != nil:
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-07-30 17:51:57 +00:00
|
|
|
if !event.Payload.HasReadPermission(authz) {
|
2020-09-08 21:31:47 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2020-10-05 16:38:38 +00:00
|
|
|
elog.Trace(event)
|
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: This conversion could be cached if needed
|
|
|
|
e := event.Payload.ToSubscriptionEvent(event.Index)
|
2020-09-08 21:31:47 +00:00
|
|
|
if err := serverStream.Send(e); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-28 22:52:31 +00:00
|
|
|
func forwardToDC(
|
2020-09-08 21:31:47 +00:00
|
|
|
req *pbsubscribe.SubscribeRequest,
|
|
|
|
serverStream pbsubscribe.StateChangeSubscription_SubscribeServer,
|
2020-09-28 22:52:31 +00:00
|
|
|
logger Logger,
|
2020-09-08 21:31:47 +00:00
|
|
|
) func(conn *grpc.ClientConn) error {
|
|
|
|
return func(conn *grpc.ClientConn) error {
|
2020-09-28 22:52:31 +00:00
|
|
|
logger.Trace("forwarding to another DC")
|
|
|
|
defer logger.Trace("forwarded stream closed")
|
2020-09-08 21:31:47 +00:00
|
|
|
|
|
|
|
client := pbsubscribe.NewStateChangeSubscriptionClient(conn)
|
|
|
|
streamHandle, err := client.Subscribe(serverStream.Context(), req)
|
2020-09-08 19:22:35 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-09-08 21:31:47 +00:00
|
|
|
for {
|
|
|
|
event, err := streamHandle.Recv()
|
|
|
|
if err != nil {
|
2020-09-08 19:22:35 +00:00
|
|
|
return err
|
|
|
|
}
|
2020-09-08 21:31:47 +00:00
|
|
|
if err := serverStream.Send(event); err != nil {
|
2020-09-08 19:22:35 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|