open-consul/agent/proxycfg-glue/health.go
Daniel Upton 70f29942f4 proxycfg-glue: server-local implementation of the Health interface
This is the OSS portion of enterprise PR 2249.

This PR introduces an implementation of the proxycfg.Health interface based on a
local materialized view of the health events.

It reuses the view and request machinery from agent/rpcclient/health, which made
it super straightforward.
2022-07-14 18:22:12 +01:00

83 lines
2.3 KiB
Go

package proxycfgglue
import (
"context"
"github.com/hashicorp/consul/agent/cache"
"github.com/hashicorp/consul/agent/proxycfg"
"github.com/hashicorp/consul/agent/rpcclient/health"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/agent/submatview"
)
// ClientHealth satisfies the proxycfg.Health interface by sourcing data from
// the given health.Client.
func ClientHealth(client *health.Client) proxycfg.Health {
return &clientHealth{client}
}
type clientHealth struct {
client *health.Client
}
func (h *clientHealth) Notify(
ctx context.Context,
req *structs.ServiceSpecificRequest,
correlationID string,
ch chan<- proxycfg.UpdateEvent,
) error {
return h.client.Notify(ctx, *req, correlationID, dispatchCacheUpdate(ch))
}
// ServerHealth satisfies the proxycfg.Health interface by sourcing data from
// a local materialized view (backed by an EventPublisher subscription).
//
// Requests for services in remote datacenters will be delegated to the given
// remoteSource (i.e. ClientHealth).
func ServerHealth(deps ServerDataSourceDeps, remoteSource proxycfg.Health) proxycfg.Health {
return &serverHealth{deps, remoteSource}
}
type serverHealth struct {
deps ServerDataSourceDeps
remoteSource proxycfg.Health
}
func (h *serverHealth) Notify(ctx context.Context, req *structs.ServiceSpecificRequest, correlationID string, ch chan<- proxycfg.UpdateEvent) error {
if req.Datacenter != h.deps.Datacenter {
return h.remoteSource.Notify(ctx, req, correlationID, ch)
}
return h.deps.ViewStore.NotifyCallback(
ctx,
&healthRequest{h.deps, *req},
correlationID,
dispatchCacheUpdate(ch),
)
}
type healthRequest struct {
deps ServerDataSourceDeps
req structs.ServiceSpecificRequest
}
func (r *healthRequest) CacheInfo() cache.RequestInfo { return r.req.CacheInfo() }
func (r *healthRequest) NewMaterializer() (submatview.Materializer, error) {
view, err := health.NewHealthView(r.req)
if err != nil {
return nil, err
}
return submatview.NewLocalMaterializer(submatview.LocalMaterializerDeps{
Backend: r.deps.EventPublisher,
ACLResolver: r.deps.ACLResolver,
Deps: submatview.Deps{
View: view,
Logger: r.deps.Logger,
Request: health.NewMaterializerRequest(r.req),
},
}), nil
}
func (r *healthRequest) Type() string { return "proxycfgglue.Health" }