open-consul/proto/pbconfigentry/config_entry.go
Daniel Upton 21ea217b1d proxycfg: server-local intentions data source
This is the OSS portion of enterprise PR 2141.

This commit provides a server-local implementation of the `proxycfg.Intentions`
interface that sources data from streaming events.

It adds events for the `service-intentions` config entry type, and then consumes
event streams (via materialized views) for the service's explicit intentions and
any applicable wildcard intentions, merging them into a single list of intentions.

An alternative approach I considered was to consume _all_ intention events (via
`SubjectWildcard`) and filter out the irrelevant ones. This would admittedly
remove some complexity in the `agent/proxycfg-glue` package but at the expense
of considerable overhead from waking potentially many thousands of connect
proxies every time any intention is updated.
2022-07-04 10:48:36 +01:00

173 lines
4.9 KiB
Go

package pbconfigentry
import (
"fmt"
"time"
"github.com/golang/protobuf/ptypes/timestamp"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/proto/pbcommon"
"github.com/hashicorp/consul/types"
)
func ConfigEntryToStructs(s *ConfigEntry) structs.ConfigEntry {
switch s.Kind {
case Kind_KindMeshConfig:
var target structs.MeshConfigEntry
MeshConfigToStructs(s.GetMeshConfig(), &target)
pbcommon.RaftIndexToStructs(s.RaftIndex, &target.RaftIndex)
pbcommon.EnterpriseMetaToStructs(s.EnterpriseMeta, &target.EnterpriseMeta)
return &target
case Kind_KindServiceResolver:
var target structs.ServiceResolverConfigEntry
target.Name = s.Name
ServiceResolverToStructs(s.GetServiceResolver(), &target)
pbcommon.RaftIndexToStructs(s.RaftIndex, &target.RaftIndex)
pbcommon.EnterpriseMetaToStructs(s.EnterpriseMeta, &target.EnterpriseMeta)
return &target
case Kind_KindIngressGateway:
var target structs.IngressGatewayConfigEntry
target.Name = s.Name
IngressGatewayToStructs(s.GetIngressGateway(), &target)
pbcommon.RaftIndexToStructs(s.RaftIndex, &target.RaftIndex)
pbcommon.EnterpriseMetaToStructs(s.EnterpriseMeta, &target.EnterpriseMeta)
return &target
case Kind_KindServiceIntentions:
var target structs.ServiceIntentionsConfigEntry
target.Name = s.Name
ServiceIntentionsToStructs(s.GetServiceIntentions(), &target)
pbcommon.RaftIndexToStructs(s.RaftIndex, &target.RaftIndex)
pbcommon.EnterpriseMetaToStructs(s.EnterpriseMeta, &target.EnterpriseMeta)
return &target
default:
panic(fmt.Sprintf("unable to convert ConfigEntry of kind %s to structs", s.Kind))
}
}
func ConfigEntryFromStructs(s structs.ConfigEntry) *ConfigEntry {
configEntry := &ConfigEntry{
Name: s.GetName(),
EnterpriseMeta: pbcommon.NewEnterpriseMetaFromStructs(*s.GetEnterpriseMeta()),
}
var raftIndex pbcommon.RaftIndex
pbcommon.RaftIndexFromStructs(s.GetRaftIndex(), &raftIndex)
configEntry.RaftIndex = &raftIndex
switch v := s.(type) {
case *structs.MeshConfigEntry:
var meshConfig MeshConfig
MeshConfigFromStructs(v, &meshConfig)
configEntry.Kind = Kind_KindMeshConfig
configEntry.Entry = &ConfigEntry_MeshConfig{
MeshConfig: &meshConfig,
}
case *structs.ServiceResolverConfigEntry:
var serviceResolver ServiceResolver
ServiceResolverFromStructs(v, &serviceResolver)
configEntry.Kind = Kind_KindServiceResolver
configEntry.Entry = &ConfigEntry_ServiceResolver{
ServiceResolver: &serviceResolver,
}
case *structs.IngressGatewayConfigEntry:
var ingressGateway IngressGateway
IngressGatewayFromStructs(v, &ingressGateway)
configEntry.Kind = Kind_KindIngressGateway
configEntry.Entry = &ConfigEntry_IngressGateway{
IngressGateway: &ingressGateway,
}
case *structs.ServiceIntentionsConfigEntry:
var serviceIntentions ServiceIntentions
ServiceIntentionsFromStructs(v, &serviceIntentions)
configEntry.Kind = Kind_KindServiceIntentions
configEntry.Entry = &ConfigEntry_ServiceIntentions{
ServiceIntentions: &serviceIntentions,
}
default:
panic(fmt.Sprintf("unable to convert %T to proto", s))
}
return configEntry
}
func tlsVersionToStructs(s string) types.TLSVersion {
return types.TLSVersion(s)
}
func tlsVersionFromStructs(t types.TLSVersion) string {
return t.String()
}
func cipherSuitesToStructs(cs []string) []types.TLSCipherSuite {
cipherSuites := make([]types.TLSCipherSuite, len(cs))
for idx, suite := range cs {
cipherSuites[idx] = types.TLSCipherSuite(suite)
}
return cipherSuites
}
func cipherSuitesFromStructs(cs []types.TLSCipherSuite) []string {
cipherSuites := make([]string, len(cs))
for idx, suite := range cs {
cipherSuites[idx] = suite.String()
}
return cipherSuites
}
func enterpriseMetaToStructs(m *pbcommon.EnterpriseMeta) acl.EnterpriseMeta {
var entMeta acl.EnterpriseMeta
pbcommon.EnterpriseMetaToStructs(m, &entMeta)
return entMeta
}
func enterpriseMetaFromStructs(m acl.EnterpriseMeta) *pbcommon.EnterpriseMeta {
return pbcommon.NewEnterpriseMetaFromStructs(m)
}
func timeFromStructs(t *time.Time) *timestamp.Timestamp {
if t == nil {
return nil
}
return timestamppb.New(*t)
}
func timeToStructs(ts *timestamp.Timestamp) *time.Time {
if ts == nil {
return nil
}
t := ts.AsTime()
return &t
}
func intentionActionFromStructs(a structs.IntentionAction) IntentionAction {
if a == structs.IntentionActionAllow {
return IntentionAction_Allow
}
return IntentionAction_Deny
}
func intentionActionToStructs(a IntentionAction) structs.IntentionAction {
if a == IntentionAction_Allow {
return structs.IntentionActionAllow
}
return structs.IntentionActionDeny
}
func intentionSourceTypeFromStructs(structs.IntentionSourceType) IntentionSourceType {
return IntentionSourceType_Consul
}
func intentionSourceTypeToStructs(IntentionSourceType) structs.IntentionSourceType {
return structs.IntentionSourceConsul
}