21ea217b1d
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.
58 lines
1.7 KiB
Go
58 lines
1.7 KiB
Go
package state
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/consul/acl"
|
|
"github.com/hashicorp/consul/agent/consul/stream"
|
|
"github.com/hashicorp/consul/proto/pbsubscribe"
|
|
)
|
|
|
|
func PBToStreamSubscribeRequest(req *pbsubscribe.SubscribeRequest, entMeta acl.EnterpriseMeta) (*stream.SubscribeRequest, error) {
|
|
var subject stream.Subject
|
|
|
|
if req.GetWildcardSubject() {
|
|
subject = stream.SubjectWildcard
|
|
} else {
|
|
named := req.GetNamedSubject()
|
|
|
|
// Support the (deprcated) top-level Key, Partition, Namespace, and PeerName fields.
|
|
if named == nil {
|
|
named = &pbsubscribe.NamedSubject{
|
|
Key: req.Key, // nolint:staticcheck // SA1019 intentional use of deprecated field
|
|
Partition: req.Partition, // nolint:staticcheck // SA1019 intentional use of deprecated field
|
|
Namespace: req.Namespace, // nolint:staticcheck // SA1019 intentional use of deprecated field
|
|
PeerName: req.PeerName, // nolint:staticcheck // SA1019 intentional use of deprecated field
|
|
}
|
|
}
|
|
|
|
if named.Key == "" {
|
|
return nil, errors.New("either WildcardSubject or NamedSubject.Key is required")
|
|
}
|
|
|
|
switch req.Topic {
|
|
case EventTopicServiceHealth, EventTopicServiceHealthConnect:
|
|
subject = EventSubjectService{
|
|
Key: named.Key,
|
|
EnterpriseMeta: entMeta,
|
|
PeerName: named.PeerName,
|
|
}
|
|
case EventTopicMeshConfig, EventTopicServiceResolver, EventTopicIngressGateway, EventTopicServiceIntentions:
|
|
subject = EventSubjectConfigEntry{
|
|
Name: named.Key,
|
|
EnterpriseMeta: &entMeta,
|
|
}
|
|
default:
|
|
return nil, fmt.Errorf("cannot construct subject for topic %s", req.Topic)
|
|
}
|
|
}
|
|
|
|
return &stream.SubscribeRequest{
|
|
Topic: req.Topic,
|
|
Subject: subject,
|
|
Token: req.Token,
|
|
Index: req.Index,
|
|
}, nil
|
|
}
|