2018-10-03 12:36:38 +00:00
|
|
|
package proxycfg
|
|
|
|
|
|
|
|
import (
|
2019-06-18 00:52:01 +00:00
|
|
|
"context"
|
|
|
|
|
2018-10-03 12:36:38 +00:00
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
|
|
|
"github.com/mitchellh/copystructure"
|
|
|
|
)
|
|
|
|
|
2019-06-18 00:52:01 +00:00
|
|
|
type configSnapshotConnectProxy struct {
|
|
|
|
Leaf *structs.IssuedCert
|
|
|
|
UpstreamEndpoints map[string]structs.CheckServiceNodes
|
|
|
|
}
|
|
|
|
|
|
|
|
type configSnapshotMeshGateway struct {
|
|
|
|
WatchedServices map[string]context.CancelFunc
|
|
|
|
WatchedDatacenters map[string]context.CancelFunc
|
|
|
|
ServiceGroups map[string]structs.CheckServiceNodes
|
|
|
|
GatewayGroups map[string]structs.CheckServiceNodes
|
|
|
|
}
|
|
|
|
|
2018-10-03 12:36:38 +00:00
|
|
|
// ConfigSnapshot captures all the resulting config needed for a proxy instance.
|
|
|
|
// 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).
|
|
|
|
type ConfigSnapshot struct {
|
2019-06-18 00:52:01 +00:00
|
|
|
Kind structs.ServiceKind
|
|
|
|
Service string
|
|
|
|
ProxyID string
|
|
|
|
Address string
|
|
|
|
Port int
|
|
|
|
TaggedAddresses map[string]structs.ServiceAddress
|
|
|
|
Proxy structs.ConnectProxyConfig
|
|
|
|
Datacenter string
|
|
|
|
Roots *structs.IndexedCARoots
|
|
|
|
|
|
|
|
// connect-proxy specific
|
|
|
|
ConnectProxy configSnapshotConnectProxy
|
|
|
|
|
|
|
|
// mesh-gateway specific
|
|
|
|
MeshGateway configSnapshotMeshGateway
|
2018-10-03 12:36:38 +00:00
|
|
|
|
|
|
|
// Skip intentions for now as we don't push those down yet, just pre-warm them.
|
|
|
|
}
|
|
|
|
|
|
|
|
// Valid returns whether or not the snapshot has all required fields filled yet.
|
|
|
|
func (s *ConfigSnapshot) Valid() bool {
|
2019-06-24 19:05:36 +00:00
|
|
|
switch s.Kind {
|
|
|
|
case structs.ServiceKindConnectProxy:
|
2019-06-18 00:52:01 +00:00
|
|
|
return s.Roots != nil && s.ConnectProxy.Leaf != nil
|
|
|
|
case structs.ServiceKindMeshGateway:
|
|
|
|
// TODO (mesh-gateway) - what happens if all the connect services go away
|
|
|
|
return s.Roots != nil && len(s.MeshGateway.ServiceGroups) > 0
|
2019-06-24 19:05:36 +00:00
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
2018-10-03 12:36:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clone makes a deep copy of the snapshot we can send to other goroutines
|
|
|
|
// without worrying that they will racily read or mutate shared maps etc.
|
|
|
|
func (s *ConfigSnapshot) Clone() (*ConfigSnapshot, error) {
|
|
|
|
snapCopy, err := copystructure.Copy(s)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-06-18 00:52:01 +00:00
|
|
|
|
|
|
|
snap := snapCopy.(*ConfigSnapshot)
|
|
|
|
|
|
|
|
switch s.Kind {
|
|
|
|
case structs.ServiceKindMeshGateway:
|
|
|
|
// nil these out as anything receiving one of these clones does not need them and should never "cancel" our watches
|
|
|
|
snap.MeshGateway.WatchedDatacenters = nil
|
|
|
|
snap.MeshGateway.WatchedServices = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return snap, nil
|
2018-10-03 12:36:38 +00:00
|
|
|
}
|