2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
2023-08-11 13:12:13 +00:00
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
2023-03-28 18:39:22 +00:00
|
|
|
|
2022-07-01 15:18:33 +00:00
|
|
|
package proxycfgglue
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/hashicorp/go-memdb"
|
|
|
|
|
2022-09-01 14:45:07 +00:00
|
|
|
"github.com/hashicorp/consul/agent/cache"
|
|
|
|
cachetype "github.com/hashicorp/consul/agent/cache-types"
|
2024-02-08 20:25:42 +00:00
|
|
|
"github.com/hashicorp/consul/agent/consul"
|
2022-07-01 15:18:33 +00:00
|
|
|
"github.com/hashicorp/consul/agent/consul/watch"
|
|
|
|
"github.com/hashicorp/consul/agent/proxycfg"
|
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
|
|
|
"github.com/hashicorp/consul/agent/structs/aclfilter"
|
|
|
|
)
|
|
|
|
|
2022-09-01 14:45:07 +00:00
|
|
|
// CacheIntentionUpstreams satisfies the proxycfg.IntentionUpstreams interface
|
2022-09-01 14:47:06 +00:00
|
|
|
// by sourcing upstreams for the given service, inferred from intentions, from
|
|
|
|
// the agent cache.
|
2022-09-01 14:45:07 +00:00
|
|
|
func CacheIntentionUpstreams(c *cache.Cache) proxycfg.IntentionUpstreams {
|
|
|
|
return &cacheProxyDataSource[*structs.ServiceSpecificRequest]{c, cachetype.IntentionUpstreamsName}
|
|
|
|
}
|
|
|
|
|
2022-09-01 14:47:06 +00:00
|
|
|
// CacheIntentionUpstreamsDestination satisfies the proxycfg.IntentionUpstreams
|
|
|
|
// interface by sourcing upstreams for the given destination, inferred from
|
|
|
|
// intentions, from the agent cache.
|
|
|
|
func CacheIntentionUpstreamsDestination(c *cache.Cache) proxycfg.IntentionUpstreams {
|
|
|
|
return &cacheProxyDataSource[*structs.ServiceSpecificRequest]{c, cachetype.IntentionUpstreamsDestinationName}
|
|
|
|
}
|
|
|
|
|
2022-07-01 15:18:33 +00:00
|
|
|
// ServerIntentionUpstreams satisfies the proxycfg.IntentionUpstreams interface
|
2022-09-01 14:47:06 +00:00
|
|
|
// by sourcing upstreams for the given service, inferred from intentions, from
|
|
|
|
// the server's state store.
|
2024-02-08 20:25:42 +00:00
|
|
|
func ServerIntentionUpstreams(deps ServerDataSourceDeps, defaultIntentionPolicy string) proxycfg.IntentionUpstreams {
|
|
|
|
return serverIntentionUpstreams{deps, structs.IntentionTargetService, defaultIntentionPolicy}
|
2022-09-01 14:47:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ServerIntentionUpstreamsDestination satisfies the proxycfg.IntentionUpstreams
|
|
|
|
// interface by sourcing upstreams for the given destination, inferred from
|
|
|
|
// intentions, from the server's state store.
|
2024-02-08 20:25:42 +00:00
|
|
|
func ServerIntentionUpstreamsDestination(deps ServerDataSourceDeps, defaultIntentionPolicy string) proxycfg.IntentionUpstreams {
|
|
|
|
return serverIntentionUpstreams{deps, structs.IntentionTargetDestination, defaultIntentionPolicy}
|
2022-07-01 15:18:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type serverIntentionUpstreams struct {
|
2024-02-08 20:25:42 +00:00
|
|
|
deps ServerDataSourceDeps
|
|
|
|
target structs.IntentionTargetType
|
|
|
|
defaultIntentionPolicy string
|
2022-07-01 15:18:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s serverIntentionUpstreams) Notify(ctx context.Context, req *structs.ServiceSpecificRequest, correlationID string, ch chan<- proxycfg.UpdateEvent) error {
|
|
|
|
target := structs.NewServiceName(req.ServiceName, &req.EnterpriseMeta)
|
|
|
|
|
|
|
|
return watch.ServerLocalNotify(ctx, correlationID, s.deps.GetStore,
|
|
|
|
func(ws memdb.WatchSet, store Store) (uint64, *structs.IndexedServiceList, error) {
|
|
|
|
authz, err := s.deps.ACLResolver.ResolveTokenAndDefaultMeta(req.Token, &req.EnterpriseMeta, nil)
|
|
|
|
if err != nil {
|
|
|
|
return 0, nil, err
|
|
|
|
}
|
|
|
|
|
2024-02-08 20:25:42 +00:00
|
|
|
defaultAllow := consul.DefaultIntentionAllow(authz, s.defaultIntentionPolicy)
|
|
|
|
|
|
|
|
index, services, err := store.IntentionTopology(ws, target, false, defaultAllow, s.target)
|
2022-07-01 15:18:33 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
result := &structs.IndexedServiceList{
|
|
|
|
Services: services,
|
|
|
|
QueryMeta: structs.QueryMeta{
|
|
|
|
Index: index,
|
|
|
|
Backend: structs.QueryBackendBlocking,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
aclfilter.New(authz, s.deps.Logger).Filter(result)
|
|
|
|
|
|
|
|
return index, result, nil
|
|
|
|
},
|
|
|
|
dispatchBlockingQueryUpdate[*structs.IndexedServiceList](ch),
|
|
|
|
)
|
|
|
|
}
|