mirror of https://github.com/status-im/consul.git
Prepare for having different service kinds that are all generic… (#6013)
Default to internal error when service kind is unknown
This commit is contained in:
parent
43c5ba0304
commit
813e009a2d
|
@ -9,6 +9,7 @@ import (
|
||||||
// It is meant to be point-in-time coherent and is used to deliver the current
|
// It is meant to be point-in-time coherent and is used to deliver the current
|
||||||
// config state to observers who need it to be pushed in (e.g. XDS server).
|
// config state to observers who need it to be pushed in (e.g. XDS server).
|
||||||
type ConfigSnapshot struct {
|
type ConfigSnapshot struct {
|
||||||
|
Kind structs.ServiceKind
|
||||||
ProxyID string
|
ProxyID string
|
||||||
Address string
|
Address string
|
||||||
Port int
|
Port int
|
||||||
|
@ -22,7 +23,12 @@ type ConfigSnapshot struct {
|
||||||
|
|
||||||
// Valid returns whether or not the snapshot has all required fields filled yet.
|
// Valid returns whether or not the snapshot has all required fields filled yet.
|
||||||
func (s *ConfigSnapshot) Valid() bool {
|
func (s *ConfigSnapshot) Valid() bool {
|
||||||
return s.Roots != nil && s.Leaf != nil
|
switch s.Kind {
|
||||||
|
case structs.ServiceKindConnectProxy:
|
||||||
|
return s.Roots != nil && s.Leaf != nil
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone makes a deep copy of the snapshot we can send to other goroutines
|
// Clone makes a deep copy of the snapshot we can send to other goroutines
|
||||||
|
|
|
@ -38,6 +38,7 @@ type state struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel func()
|
cancel func()
|
||||||
|
|
||||||
|
kind structs.ServiceKind
|
||||||
proxyID string
|
proxyID string
|
||||||
address string
|
address string
|
||||||
port int
|
port int
|
||||||
|
@ -72,6 +73,7 @@ func newState(ns *structs.NodeService, token string) (*state, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &state{
|
return &state{
|
||||||
|
kind: ns.Kind,
|
||||||
proxyID: ns.ID,
|
proxyID: ns.ID,
|
||||||
address: ns.Address,
|
address: ns.Address,
|
||||||
port: ns.Port,
|
port: ns.Port,
|
||||||
|
@ -116,9 +118,19 @@ func (s *state) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// initWatches sets up the watches needed based on current proxy registration
|
// initWatches sets up the watches needed for the particular service
|
||||||
// state.
|
|
||||||
func (s *state) initWatches() error {
|
func (s *state) initWatches() error {
|
||||||
|
switch s.kind {
|
||||||
|
case structs.ServiceKindConnectProxy:
|
||||||
|
return s.initWatchesConnectProxy()
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Unsupported service kind")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// initWatchesConnectProxy sets up the watches needed based on current proxy registration
|
||||||
|
// state.
|
||||||
|
func (s *state) initWatchesConnectProxy() error {
|
||||||
// Watch for root changes
|
// Watch for root changes
|
||||||
err := s.cache.Notify(s.ctx, cachetype.ConnectCARootName, &structs.DCSpecificRequest{
|
err := s.cache.Notify(s.ctx, cachetype.ConnectCARootName, &structs.DCSpecificRequest{
|
||||||
Datacenter: s.source.Datacenter,
|
Datacenter: s.source.Datacenter,
|
||||||
|
@ -203,12 +215,18 @@ func (s *state) run() {
|
||||||
defer close(s.snapCh)
|
defer close(s.snapCh)
|
||||||
|
|
||||||
snap := ConfigSnapshot{
|
snap := ConfigSnapshot{
|
||||||
ProxyID: s.proxyID,
|
Kind: s.kind,
|
||||||
Address: s.address,
|
ProxyID: s.proxyID,
|
||||||
Port: s.port,
|
Address: s.address,
|
||||||
Proxy: s.proxyCfg,
|
Port: s.port,
|
||||||
UpstreamEndpoints: make(map[string]structs.CheckServiceNodes),
|
Proxy: s.proxyCfg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch s.kind {
|
||||||
|
case structs.ServiceKindConnectProxy:
|
||||||
|
snap.UpstreamEndpoints = make(map[string]structs.CheckServiceNodes)
|
||||||
|
}
|
||||||
|
|
||||||
// This turns out to be really fiddly/painful by just using time.Timer.C
|
// This turns out to be really fiddly/painful by just using time.Timer.C
|
||||||
// directly in the code below since you can't detect when a timer is stopped
|
// directly in the code below since you can't detect when a timer is stopped
|
||||||
// vs waiting in order to know to reset it. So just use a chan to send
|
// vs waiting in order to know to reset it. So just use a chan to send
|
||||||
|
@ -282,6 +300,15 @@ func (s *state) run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *state) handleUpdate(u cache.UpdateEvent, snap *ConfigSnapshot) error {
|
func (s *state) handleUpdate(u cache.UpdateEvent, snap *ConfigSnapshot) error {
|
||||||
|
switch s.kind {
|
||||||
|
case structs.ServiceKindConnectProxy:
|
||||||
|
return s.handleUpdateConnectProxy(u, snap)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Unsupported service kind")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *state) handleUpdateConnectProxy(u cache.UpdateEvent, snap *ConfigSnapshot) error {
|
||||||
switch u.CorrelationID {
|
switch u.CorrelationID {
|
||||||
case rootsWatchID:
|
case rootsWatchID:
|
||||||
roots, ok := u.Result.(*structs.IndexedCARoots)
|
roots, ok := u.Result.(*structs.IndexedCARoots)
|
||||||
|
@ -340,7 +367,7 @@ func (s *state) Changed(ns *structs.NodeService, token string) bool {
|
||||||
if ns == nil {
|
if ns == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return ns.Kind != structs.ServiceKindConnectProxy ||
|
return ns.Kind != s.kind ||
|
||||||
s.proxyID != ns.ID ||
|
s.proxyID != ns.ID ||
|
||||||
s.address != ns.Address ||
|
s.address != ns.Address ||
|
||||||
s.port != ns.Port ||
|
s.port != ns.Port ||
|
||||||
|
|
|
@ -19,9 +19,23 @@ import (
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// clustersFromSnapshot returns the xDS API representation of the "clusters" in the snapshot.
|
||||||
|
func (s *Server) clustersFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error) {
|
||||||
|
if cfgSnap == nil {
|
||||||
|
return nil, errors.New("nil config given")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch cfgSnap.Kind {
|
||||||
|
case structs.ServiceKindConnectProxy:
|
||||||
|
return s.clustersFromSnapshotConnectProxy(cfgSnap, token)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Invalid service kind: %v", cfgSnap.Kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// clustersFromSnapshot returns the xDS API representation of the "clusters"
|
// clustersFromSnapshot returns the xDS API representation of the "clusters"
|
||||||
// (upstreams) in the snapshot.
|
// (upstreams) in the snapshot.
|
||||||
func (s *Server) clustersFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error) {
|
func (s *Server) clustersFromSnapshotConnectProxy(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error) {
|
||||||
if cfgSnap == nil {
|
if cfgSnap == nil {
|
||||||
return nil, errors.New("nil config given")
|
return nil, errors.New("nil config given")
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package xds
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
||||||
envoycore "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
|
envoycore "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
|
||||||
|
@ -14,11 +15,25 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// endpointsFromSnapshot returns the xDS API representation of the "endpoints"
|
// endpointsFromSnapshot returns the xDS API representation of the "endpoints"
|
||||||
// (upstream instances) in the snapshot.
|
|
||||||
func endpointsFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error) {
|
func endpointsFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error) {
|
||||||
if cfgSnap == nil {
|
if cfgSnap == nil {
|
||||||
return nil, errors.New("nil config given")
|
return nil, errors.New("nil config given")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch cfgSnap.Kind {
|
||||||
|
case structs.ServiceKindConnectProxy:
|
||||||
|
return endpointsFromSnapshotConnectProxy(cfgSnap, token)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Invalid service kind: %v", cfgSnap.Kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// endpointsFromSnapshotConnectProxy returns the xDS API representation of the "endpoints"
|
||||||
|
// (upstream instances) in the snapshot.
|
||||||
|
func endpointsFromSnapshotConnectProxy(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error) {
|
||||||
|
if cfgSnap == nil {
|
||||||
|
return nil, errors.New("nil config given")
|
||||||
|
}
|
||||||
resources := make([]proto.Message, 0, len(cfgSnap.UpstreamEndpoints))
|
resources := make([]proto.Message, 0, len(cfgSnap.UpstreamEndpoints))
|
||||||
for id, endpoints := range cfgSnap.UpstreamEndpoints {
|
for id, endpoints := range cfgSnap.UpstreamEndpoints {
|
||||||
la := makeLoadAssignment(id, endpoints)
|
la := makeLoadAssignment(id, endpoints)
|
||||||
|
|
|
@ -24,13 +24,27 @@ import (
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// listenersFromSnapshot returns the xDS API representation of the "listeners"
|
// listenersFromSnapshot returns the xDS API representation of the "listeners" in the snapshot.
|
||||||
// in the snapshot.
|
|
||||||
func (s *Server) listenersFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error) {
|
func (s *Server) listenersFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error) {
|
||||||
if cfgSnap == nil {
|
if cfgSnap == nil {
|
||||||
return nil, errors.New("nil config given")
|
return nil, errors.New("nil config given")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch cfgSnap.Kind {
|
||||||
|
case structs.ServiceKindConnectProxy:
|
||||||
|
return s.listenersFromSnapshotConnectProxy(cfgSnap, token)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Invalid service kind: %v", cfgSnap.Kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// listenersFromSnapshotConnectProxy returns the xDS API representation of the "listeners"
|
||||||
|
// in the snapshot.
|
||||||
|
func (s *Server) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error) {
|
||||||
|
if cfgSnap == nil {
|
||||||
|
return nil, errors.New("nil config given")
|
||||||
|
}
|
||||||
|
|
||||||
// One listener for each upstream plus the public one
|
// One listener for each upstream plus the public one
|
||||||
resources := make([]proto.Message, len(cfgSnap.Proxy.Upstreams)+1)
|
resources := make([]proto.Message, len(cfgSnap.Proxy.Upstreams)+1)
|
||||||
|
|
||||||
|
|
|
@ -235,8 +235,13 @@ func (s *Server) process(stream ADSStream, reqCh <-chan *envoy.DiscoveryRequest)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if rule != nil && !rule.ServiceWrite(cfgSnap.Proxy.DestinationServiceName, nil) {
|
switch cfgSnap.Kind {
|
||||||
return status.Errorf(codes.PermissionDenied, "permission denied")
|
case structs.ServiceKindConnectProxy:
|
||||||
|
if rule != nil && !rule.ServiceWrite(cfgSnap.Proxy.DestinationServiceName, nil) {
|
||||||
|
return status.Errorf(codes.PermissionDenied, "permission denied")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return status.Errorf(codes.Internal, "Invalid service kind")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authed OK!
|
// Authed OK!
|
||||||
|
|
Loading…
Reference in New Issue