mirror of https://github.com/status-im/consul.git
mesh: use ComputedImplicitDestinations resource in the sidecar controller (#20553)
Wire the ComputedImplicitDestinations resource into the sidecar controller, replacing the inline version already present. Also: - Rewrite the controller to use the controller cache - Rewrite it to no longer depend on ServiceEndpoints - Remove the fetcher and (local) cache abstraction
This commit is contained in:
parent
7e8f2e5f08
commit
671c436415
|
@ -36,3 +36,36 @@ func MakeRequests[V resource.ReferenceOrID](
|
|||
|
||||
return out
|
||||
}
|
||||
|
||||
// MakeRequestsFromResources accepts a list of items and converts them into a
|
||||
// slice of []controller.Request items where the Type of the items has replaced
|
||||
// by 'typ'.
|
||||
func MakeRequestsFromResources[V interface {
|
||||
GetId() *pbresource.ID
|
||||
}](
|
||||
typ *pbresource.Type,
|
||||
resources []V,
|
||||
) []Request {
|
||||
if len(resources) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := make([]Request, 0, len(resources))
|
||||
for _, res := range resources {
|
||||
id := res.GetId()
|
||||
|
||||
// if type is not provided, we will use the type in the ID or reference.
|
||||
if typ == nil {
|
||||
typ = id.GetType()
|
||||
}
|
||||
out = append(out, Request{
|
||||
ID: &pbresource.ID{
|
||||
Type: typ,
|
||||
Tenancy: id.GetTenancy(),
|
||||
Name: id.GetName(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/gatewayproxy/fetcher"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/meshgateways"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/multicluster"
|
||||
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
|
@ -188,8 +187,7 @@ func (suite *proxyStateTemplateBuilderSuite) setupWithTenancy(tenancy *pbresourc
|
|||
|
||||
func (suite *proxyStateTemplateBuilderSuite) TestProxyStateTemplateBuilder_BuildForPeeredExportedServices() {
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
c := cache.New()
|
||||
f := fetcher.New(suite.client, c)
|
||||
f := fetcher.New(suite.client)
|
||||
dc := "dc"
|
||||
trustDomain := "trustDomain"
|
||||
logger := testutil.Logger(suite.T())
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/gatewayproxy/mapper"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/meshgateways"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
|
@ -33,7 +32,7 @@ const (
|
|||
)
|
||||
|
||||
// Controller is responsible for triggering reconciler for watched resources
|
||||
func Controller(cache *cache.Cache, trustDomainFetcher sidecarproxy.TrustDomainFetcher, dc string, defaultAllow bool) *controller.Controller {
|
||||
func Controller(trustDomainFetcher sidecarproxy.TrustDomainFetcher, dc string, defaultAllow bool) *controller.Controller {
|
||||
// TODO NET-7016 Use caching functionality in NewController being implemented at time of writing
|
||||
// TODO NET-7017 Add the host of other types we should watch
|
||||
// TODO NET-7565: Add watch for serviceTypes across partitions
|
||||
|
@ -42,7 +41,6 @@ func Controller(cache *cache.Cache, trustDomainFetcher sidecarproxy.TrustDomainF
|
|||
WithWatch(pbmesh.ComputedProxyConfigurationType, dependency.ReplaceType(pbmesh.ProxyStateTemplateType)).
|
||||
WithWatch(pbmulticluster.ComputedExportedServicesType, mapper.AllMeshGatewayWorkloadsInPartition).
|
||||
WithReconciler(&reconciler{
|
||||
cache: cache,
|
||||
dc: dc,
|
||||
defaultAllow: defaultAllow,
|
||||
getTrustDomain: trustDomainFetcher,
|
||||
|
@ -52,7 +50,6 @@ func Controller(cache *cache.Cache, trustDomainFetcher sidecarproxy.TrustDomainF
|
|||
// reconciler is responsible for managing the ProxyStateTemplate for all
|
||||
// gateway types: mesh, api (future) and terminating (future).
|
||||
type reconciler struct {
|
||||
cache *cache.Cache
|
||||
dc string
|
||||
defaultAllow bool
|
||||
getTrustDomain sidecarproxy.TrustDomainFetcher
|
||||
|
@ -67,7 +64,7 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c
|
|||
rt.Logger.Trace("reconciling proxy state template")
|
||||
|
||||
// Instantiate a data fetcher to fetch all reconciliation data.
|
||||
dataFetcher := fetcher.New(rt.Client, r.cache)
|
||||
dataFetcher := fetcher.New(rt.Client)
|
||||
|
||||
workloadID := resource.ReplaceType(pbcatalog.WorkloadType, req.ID)
|
||||
workload, err := dataFetcher.FetchWorkload(ctx, workloadID)
|
||||
|
|
|
@ -7,25 +7,23 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type Fetcher struct {
|
||||
client pbresource.ResourceServiceClient
|
||||
cache *cache.Cache
|
||||
}
|
||||
|
||||
func New(client pbresource.ResourceServiceClient, cache *cache.Cache) *Fetcher {
|
||||
func New(client pbresource.ResourceServiceClient) *Fetcher {
|
||||
return &Fetcher{
|
||||
client: client,
|
||||
cache: cache,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing"
|
||||
"github.com/hashicorp/consul/internal/catalog"
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/multicluster"
|
||||
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
|
@ -110,10 +109,7 @@ func (suite *dataFetcherSuite) setupWithTenancy(tenancy *pbresource.Tenancy) {
|
|||
|
||||
func (suite *dataFetcherSuite) TestFetcher_FetchMeshGateway() {
|
||||
suite.runTestCaseWithTenancies(func(_ *pbresource.Tenancy) {
|
||||
c := cache.New()
|
||||
|
||||
f := Fetcher{
|
||||
cache: c,
|
||||
client: suite.client,
|
||||
}
|
||||
|
||||
|
@ -143,10 +139,7 @@ func (suite *dataFetcherSuite) TestFetcher_FetchMeshGateway() {
|
|||
|
||||
func (suite *dataFetcherSuite) TestFetcher_FetchProxyStateTemplate() {
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
c := cache.New()
|
||||
|
||||
f := Fetcher{
|
||||
cache: c,
|
||||
client: suite.client,
|
||||
}
|
||||
|
||||
|
@ -176,10 +169,7 @@ func (suite *dataFetcherSuite) TestFetcher_FetchProxyStateTemplate() {
|
|||
|
||||
func (suite *dataFetcherSuite) TestFetcher_FetchWorkload() {
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
c := cache.New()
|
||||
|
||||
f := Fetcher{
|
||||
cache: c,
|
||||
client: suite.client,
|
||||
}
|
||||
|
||||
|
@ -200,10 +190,7 @@ func (suite *dataFetcherSuite) TestFetcher_FetchWorkload() {
|
|||
|
||||
func (suite *dataFetcherSuite) TestFetcher_FetchExportedServices() {
|
||||
suite.runTestCaseWithTenancies(func(_ *pbresource.Tenancy) {
|
||||
c := cache.New()
|
||||
|
||||
f := Fetcher{
|
||||
cache: c,
|
||||
client: suite.client,
|
||||
}
|
||||
|
||||
|
@ -224,10 +211,7 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExportedServices() {
|
|||
|
||||
func (suite *dataFetcherSuite) TestFetcher_FetchService() {
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
c := cache.New()
|
||||
|
||||
f := Fetcher{
|
||||
cache: c,
|
||||
client: suite.client,
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import (
|
|||
// AllMeshGatewayWorkloadsInPartition returns one controller.Request for each Workload
|
||||
// selected by a MeshGateway in the partition of the Resource.
|
||||
var AllMeshGatewayWorkloadsInPartition = func(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) {
|
||||
fetcher := fetcher.New(rt.Client, nil)
|
||||
fetcher := fetcher.New(rt.Client)
|
||||
|
||||
gateways, err := fetcher.FetchMeshGateways(ctx, &pbresource.Tenancy{
|
||||
Partition: res.Id.Tenancy.Partition,
|
||||
|
|
|
@ -6,9 +6,9 @@ package implicitdestinations
|
|||
import (
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/hashicorp/consul/internal/catalog"
|
||||
"github.com/hashicorp/consul/internal/controller/cache/index"
|
||||
"github.com/hashicorp/consul/internal/controller/cache/indexers"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/meshindexes"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
"github.com/hashicorp/consul/internal/storage"
|
||||
|
@ -33,12 +33,7 @@ import (
|
|||
var boundRefsIndex = indexers.BoundRefsIndex[*pbmesh.ComputedImplicitDestinations]("bound-references")
|
||||
|
||||
// Cache: reverse SVC[*] => WI[*]
|
||||
var serviceByWorkloadIdentityIndex = indexers.RefOrIDIndex(
|
||||
"service-by-workload-identity",
|
||||
func(svc *types.DecodedService) []*pbresource.Reference {
|
||||
return getWorkloadIdentitiesFromService(svc.Resource)
|
||||
},
|
||||
)
|
||||
var serviceByWorkloadIdentityIndex = meshindexes.ServiceByWorkloadIdentityIndex()
|
||||
|
||||
// Cache: reverse CTP => WI[source]
|
||||
var ctpBySourceWorkloadIdentityIndex = indexers.RefOrIDIndex(
|
||||
|
@ -109,26 +104,7 @@ func indexFromTenantedName(tn tenantedName) []byte {
|
|||
}
|
||||
|
||||
// Cache: reverse CR => SVC[backend]
|
||||
var computedRoutesByBackendServiceIndex = indexers.RefOrIDIndex(
|
||||
"computed-routes-by-backend-service",
|
||||
func(cr *types.DecodedComputedRoutes) []*pbresource.Reference {
|
||||
return getBackendServiceRefsFromComputedRoutes(cr)
|
||||
},
|
||||
)
|
||||
|
||||
func getWorkloadIdentitiesFromService(svc *pbresource.Resource) []*pbresource.Reference {
|
||||
ids := catalog.GetBoundIdentities(svc)
|
||||
|
||||
out := make([]*pbresource.Reference, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
out = append(out, &pbresource.Reference{
|
||||
Type: pbauth.WorkloadIdentityType,
|
||||
Name: id,
|
||||
Tenancy: svc.Id.Tenancy,
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
var computedRoutesByBackendServiceIndex = meshindexes.ComputedRoutesByBackendServiceIndex()
|
||||
|
||||
func getSourceWorkloadIdentitiesFromCTP(
|
||||
ctp *types.DecodedComputedTrafficPermissions,
|
||||
|
@ -195,24 +171,6 @@ func getSourceWorkloadIdentitiesFromCTP(
|
|||
return out, sliceWildNameInNS, sliceWildNSInPartition
|
||||
}
|
||||
|
||||
func getBackendServiceRefsFromComputedRoutes(cr *types.DecodedComputedRoutes) []*pbresource.Reference {
|
||||
var (
|
||||
out []*pbresource.Reference
|
||||
seen = make(map[resource.ReferenceKey]struct{})
|
||||
)
|
||||
for _, pc := range cr.Data.PortedConfigs {
|
||||
for _, target := range pc.Targets {
|
||||
ref := target.BackendRef.Ref
|
||||
rk := resource.NewReferenceKey(ref)
|
||||
if _, ok := seen[rk]; !ok {
|
||||
out = append(out, ref)
|
||||
seen[rk] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
type sourceType int
|
||||
|
||||
const (
|
||||
|
|
|
@ -12,75 +12,11 @@ import (
|
|||
"github.com/hashicorp/consul/internal/catalog"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
"github.com/hashicorp/consul/proto/private/prototest"
|
||||
)
|
||||
|
||||
func TestGetWorkloadIdentitiesFromService(t *testing.T) {
|
||||
tenancy := resource.DefaultNamespacedTenancy()
|
||||
|
||||
build := func(conds ...*pbresource.Condition) *pbresource.Resource {
|
||||
b := rtest.Resource(pbcatalog.ServiceType, "web").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, &pbcatalog.Service{})
|
||||
if len(conds) > 0 {
|
||||
b.WithStatus(catalog.EndpointsStatusKey, &pbresource.Status{
|
||||
Conditions: conds,
|
||||
})
|
||||
}
|
||||
return b.Build()
|
||||
}
|
||||
|
||||
fooRef := &pbresource.Reference{
|
||||
Type: pbauth.WorkloadIdentityType,
|
||||
Tenancy: tenancy,
|
||||
Name: "foo",
|
||||
}
|
||||
barRef := &pbresource.Reference{
|
||||
Type: pbauth.WorkloadIdentityType,
|
||||
Tenancy: tenancy,
|
||||
Name: "bar",
|
||||
}
|
||||
|
||||
makeRefs := func(refs ...*pbresource.Reference) []*pbresource.Reference {
|
||||
return refs
|
||||
}
|
||||
|
||||
run := getWorkloadIdentitiesFromService
|
||||
|
||||
require.Empty(t, run(build(nil)))
|
||||
require.Empty(t, run(build(&pbresource.Condition{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: "",
|
||||
})))
|
||||
prototest.AssertDeepEqual(t, makeRefs(fooRef), run(build(&pbresource.Condition{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: "foo",
|
||||
})))
|
||||
require.Empty(t, run(build(&pbresource.Condition{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_FALSE,
|
||||
Message: "foo",
|
||||
})))
|
||||
prototest.AssertDeepEqual(t, makeRefs(barRef, fooRef), run(build(&pbresource.Condition{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: "bar,foo", // proper order
|
||||
})))
|
||||
prototest.AssertDeepEqual(t, makeRefs(barRef, fooRef), run(build(&pbresource.Condition{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: "foo,bar", // incorrect order gets fixed
|
||||
})))
|
||||
}
|
||||
|
||||
func TestGetSourceWorkloadIdentitiesFromCTP(t *testing.T) {
|
||||
registry := resource.NewRegistry()
|
||||
types.Register(registry)
|
||||
|
@ -318,91 +254,3 @@ func TestGetSourceWorkloadIdentitiesFromCTP(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBackendServiceRefsFromComputedRoutes(t *testing.T) {
|
||||
type testcase struct {
|
||||
cr *types.DecodedComputedRoutes
|
||||
expect []*pbresource.Reference
|
||||
}
|
||||
|
||||
run := func(t *testing.T, tc testcase) {
|
||||
got := getBackendServiceRefsFromComputedRoutes(tc.cr)
|
||||
prototest.AssertElementsMatch(t, tc.expect, got)
|
||||
}
|
||||
|
||||
tenancy := resource.DefaultNamespacedTenancy()
|
||||
|
||||
newRef := func(name string) *pbresource.Reference {
|
||||
return &pbresource.Reference{
|
||||
Type: pbcatalog.ServiceType,
|
||||
Tenancy: tenancy,
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
cr1 := resourcetest.Resource(pbmesh.ComputedRoutesType, "cr1").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, &pbmesh.ComputedRoutes{
|
||||
PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{
|
||||
"http": {
|
||||
Targets: map[string]*pbmesh.BackendTargetDetails{
|
||||
"opaque1": {
|
||||
BackendRef: &pbmesh.BackendReference{Ref: newRef("aaa")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}).
|
||||
Build()
|
||||
|
||||
cr2 := resourcetest.Resource(pbmesh.ComputedRoutesType, "cr2").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, &pbmesh.ComputedRoutes{
|
||||
PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{
|
||||
"http": {
|
||||
Targets: map[string]*pbmesh.BackendTargetDetails{
|
||||
"opaque1": {
|
||||
BackendRef: &pbmesh.BackendReference{Ref: newRef("aaa")},
|
||||
},
|
||||
"opaque2": {
|
||||
BackendRef: &pbmesh.BackendReference{Ref: newRef("bbb")},
|
||||
},
|
||||
},
|
||||
},
|
||||
"grpc": {
|
||||
Targets: map[string]*pbmesh.BackendTargetDetails{
|
||||
"opaque2": {
|
||||
BackendRef: &pbmesh.BackendReference{Ref: newRef("bbb")},
|
||||
},
|
||||
"opaque3": {
|
||||
BackendRef: &pbmesh.BackendReference{Ref: newRef("ccc")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}).
|
||||
Build()
|
||||
|
||||
cases := map[string]testcase{
|
||||
"one": {
|
||||
cr: resourcetest.MustDecode[*pbmesh.ComputedRoutes](t, cr1),
|
||||
expect: []*pbresource.Reference{
|
||||
newRef("aaa"),
|
||||
},
|
||||
},
|
||||
"two": {
|
||||
cr: resourcetest.MustDecode[*pbmesh.ComputedRoutes](t, cr2),
|
||||
expect: []*pbresource.Reference{
|
||||
newRef("aaa"),
|
||||
newRef("bbb"),
|
||||
newRef("ccc"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
run(t, tc)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/controller/cache"
|
||||
"github.com/hashicorp/consul/internal/controller/dependency"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/meshindexes"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
"github.com/hashicorp/consul/internal/storage"
|
||||
|
@ -135,7 +136,7 @@ func (m *mapAndTransformer) transformServiceToWorkloadIdentities(ctx context.Con
|
|||
// another transformer immediately anyway, so it's largely an opaque
|
||||
// carrier for the WI name string only.
|
||||
|
||||
wiIDs := getWorkloadIdentitiesFromService(res)
|
||||
wiIDs := meshindexes.GetWorkloadIdentitiesFromService(res)
|
||||
|
||||
out := make([]*pbresource.Resource, 0, len(wiIDs))
|
||||
for _, wiID := range wiIDs {
|
||||
|
@ -154,7 +155,7 @@ func (m *mapAndTransformer) transformComputedRoutesToBackendServiceRefs(ctx cont
|
|||
return nil, err
|
||||
}
|
||||
|
||||
svcRefs := getBackendServiceRefsFromComputedRoutes(cr)
|
||||
svcRefs := meshindexes.GetBackendServiceRefsFromComputedRoutes(cr)
|
||||
|
||||
out := make([]*pbresource.Resource, 0, len(svcRefs))
|
||||
for _, svcRef := range svcRefs {
|
||||
|
|
|
@ -6,20 +6,18 @@ package controllers
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/consul/agent/leafcert"
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/apigateways"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/explicitdestinations"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/explicitdestinations/mapper"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/gatewayproxy"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/implicitdestinations"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/meshconfiguration"
|
||||
|
||||
"github.com/hashicorp/consul/agent/leafcert"
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/explicitdestinations"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/explicitdestinations/mapper"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/meshgateways"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/proxyconfiguration"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/routes"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/xds"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/mappers/workloadselectionmapper"
|
||||
"github.com/hashicorp/consul/internal/resource/mappers/bimapper"
|
||||
|
@ -47,10 +45,10 @@ func Register(mgr *controller.Manager, deps Dependencies) {
|
|||
mgr.Register(xds.Controller(endpointsMapper, deps.ProxyUpdater, deps.TrustBundleFetcher, deps.LeafCertManager, leafMapper, leafCancels, deps.LocalDatacenter))
|
||||
|
||||
mgr.Register(
|
||||
sidecarproxy.Controller(cache.New(), deps.TrustDomainFetcher, deps.LocalDatacenter, deps.DefaultAllow),
|
||||
sidecarproxy.Controller(deps.TrustDomainFetcher, deps.LocalDatacenter, deps.DefaultAllow),
|
||||
)
|
||||
|
||||
mgr.Register(gatewayproxy.Controller(cache.New(), deps.TrustDomainFetcher, deps.LocalDatacenter, deps.DefaultAllow))
|
||||
mgr.Register(gatewayproxy.Controller(deps.TrustDomainFetcher, deps.LocalDatacenter, deps.DefaultAllow))
|
||||
|
||||
mgr.Register(routes.Controller())
|
||||
|
||||
|
|
|
@ -161,7 +161,6 @@ func TestBuildMultiportImplicitDestinations(t *testing.T) {
|
|||
virtualIPs []string,
|
||||
) []*intermediate.Destination {
|
||||
svcDec := resourcetest.MustDecode[*pbcatalog.Service](t, svc)
|
||||
seDec := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](t, endpoints)
|
||||
|
||||
var out []*intermediate.Destination
|
||||
for _, port := range svcDec.Data.Ports {
|
||||
|
@ -180,7 +179,6 @@ func TestBuildMultiportImplicitDestinations(t *testing.T) {
|
|||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = seDec.Data
|
||||
details.IdentityRefs = identities
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -25,22 +25,6 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
endpointsData = &pbcatalog.ServiceEndpoints{
|
||||
Endpoints: []*pbcatalog.Endpoint{
|
||||
{
|
||||
Addresses: []*pbcatalog.WorkloadAddress{
|
||||
{Host: "10.0.0.1"},
|
||||
},
|
||||
Ports: map[string]*pbcatalog.WorkloadPort{
|
||||
"tcp": {Port: 7070, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
"tcp2": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
"http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP},
|
||||
"mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
serviceData = &pbcatalog.Service{
|
||||
Ports: []*pbcatalog.ServicePort{
|
||||
{
|
||||
|
@ -99,40 +83,19 @@ func TestBuildExplicitDestinations(t *testing.T) {
|
|||
resourcetest.ValidateAndNormalize(t, registry, res)
|
||||
}
|
||||
|
||||
api1Endpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-1").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, endpointsData).
|
||||
Build()
|
||||
|
||||
api2Endpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-2").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, endpointsData).
|
||||
Build()
|
||||
|
||||
backup1Endpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "backup-1").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, endpointsData).
|
||||
Build()
|
||||
|
||||
for _, res := range []*pbresource.Resource{
|
||||
api1Endpoints, api2Endpoints, backup1Endpoints,
|
||||
} {
|
||||
resourcetest.ValidateAndNormalize(t, registry, res)
|
||||
}
|
||||
|
||||
api1Identity := &pbresource.Reference{
|
||||
Name: "api1-identity",
|
||||
Tenancy: api1Endpoints.Id.Tenancy,
|
||||
Tenancy: tenancy,
|
||||
}
|
||||
|
||||
api2Identity := &pbresource.Reference{
|
||||
Name: "api2-identity",
|
||||
Tenancy: api2Endpoints.Id.Tenancy,
|
||||
Tenancy: tenancy,
|
||||
}
|
||||
|
||||
backup1Identity := &pbresource.Reference{
|
||||
Name: "backup1-identity",
|
||||
Tenancy: backup1Endpoints.Id.Tenancy,
|
||||
Tenancy: tenancy,
|
||||
}
|
||||
|
||||
api1DestPolicy := resourcetest.Resource(pbmesh.DestinationPolicyType, api1Service.Id.Name).
|
||||
|
@ -311,7 +274,7 @@ func TestBuildExplicitDestinations(t *testing.T) {
|
|||
|
||||
destinationIpPort := &intermediate.Destination{
|
||||
Explicit: &pbmesh.Destination{
|
||||
DestinationRef: resource.Reference(api1Endpoints.Id, ""),
|
||||
DestinationRef: resource.Reference(api1Service.Id, ""),
|
||||
DestinationPort: "tcp",
|
||||
Datacenter: "dc1",
|
||||
ListenAddr: &pbmesh.Destination_IpPort{
|
||||
|
@ -323,19 +286,17 @@ func TestBuildExplicitDestinations(t *testing.T) {
|
|||
switch {
|
||||
case resource.ReferenceOrIDMatch(api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: api1Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api1Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{api1Identity}
|
||||
case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: api2Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api2Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{api2Identity}
|
||||
}
|
||||
}),
|
||||
|
@ -343,7 +304,7 @@ func TestBuildExplicitDestinations(t *testing.T) {
|
|||
|
||||
destinationIpPort2 := &intermediate.Destination{
|
||||
Explicit: &pbmesh.Destination{
|
||||
DestinationRef: resource.Reference(api1Endpoints.Id, ""),
|
||||
DestinationRef: resource.Reference(api1Service.Id, ""),
|
||||
DestinationPort: "tcp2",
|
||||
Datacenter: "dc1",
|
||||
ListenAddr: &pbmesh.Destination_IpPort{
|
||||
|
@ -355,19 +316,17 @@ func TestBuildExplicitDestinations(t *testing.T) {
|
|||
switch {
|
||||
case resource.ReferenceOrIDMatch(api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: api1Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api1Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{api1Identity}
|
||||
case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: api2Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api2Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{api2Identity}
|
||||
}
|
||||
}),
|
||||
|
@ -375,7 +334,7 @@ func TestBuildExplicitDestinations(t *testing.T) {
|
|||
|
||||
destinationUnix := &intermediate.Destination{
|
||||
Explicit: &pbmesh.Destination{
|
||||
DestinationRef: resource.Reference(api2Endpoints.Id, ""),
|
||||
DestinationRef: resource.Reference(api2Service.Id, ""),
|
||||
DestinationPort: "tcp",
|
||||
Datacenter: "dc1",
|
||||
ListenAddr: &pbmesh.Destination_Unix{
|
||||
|
@ -387,11 +346,10 @@ func TestBuildExplicitDestinations(t *testing.T) {
|
|||
switch {
|
||||
case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: api2Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api2Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{api2Identity}
|
||||
}
|
||||
}),
|
||||
|
@ -399,7 +357,7 @@ func TestBuildExplicitDestinations(t *testing.T) {
|
|||
|
||||
destinationUnix2 := &intermediate.Destination{
|
||||
Explicit: &pbmesh.Destination{
|
||||
DestinationRef: resource.Reference(api2Endpoints.Id, ""),
|
||||
DestinationRef: resource.Reference(api2Service.Id, ""),
|
||||
DestinationPort: "tcp2",
|
||||
Datacenter: "dc1",
|
||||
ListenAddr: &pbmesh.Destination_Unix{
|
||||
|
@ -411,18 +369,17 @@ func TestBuildExplicitDestinations(t *testing.T) {
|
|||
switch {
|
||||
case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: api2Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api2Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{api2Identity}
|
||||
}
|
||||
}),
|
||||
}
|
||||
destinationIpPortHTTP := &intermediate.Destination{
|
||||
Explicit: &pbmesh.Destination{
|
||||
DestinationRef: resource.Reference(api1Endpoints.Id, ""),
|
||||
DestinationRef: resource.Reference(api1Service.Id, ""),
|
||||
DestinationPort: "http",
|
||||
Datacenter: "dc1",
|
||||
ListenAddr: &pbmesh.Destination_IpPort{
|
||||
|
@ -434,27 +391,24 @@ func TestBuildExplicitDestinations(t *testing.T) {
|
|||
switch {
|
||||
case resource.ReferenceOrIDMatch(api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "http":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: api1Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api1Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{api1Identity}
|
||||
case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "http":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: api2Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api2Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{api2Identity}
|
||||
case resource.ReferenceOrIDMatch(backup1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "http":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: backup1Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, backup1Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{backup1Identity}
|
||||
}
|
||||
}),
|
||||
|
@ -506,24 +460,14 @@ func TestBuildImplicitDestinations(t *testing.T) {
|
|||
WithData(t, serviceData).
|
||||
Build()
|
||||
|
||||
api1Endpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-1").
|
||||
WithOwner(api1Service.Id).
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, endpointsData).Build()
|
||||
|
||||
api2Endpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-2").
|
||||
WithOwner(api2Service.Id).
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, endpointsData).Build()
|
||||
|
||||
api1Identity := &pbresource.Reference{
|
||||
Name: "api1-identity",
|
||||
Tenancy: api1Endpoints.Id.Tenancy,
|
||||
Tenancy: tenancy,
|
||||
}
|
||||
|
||||
api2Identity := &pbresource.Reference{
|
||||
Name: "api2-identity",
|
||||
Tenancy: api2Endpoints.Id.Tenancy,
|
||||
Tenancy: tenancy,
|
||||
}
|
||||
|
||||
api1ComputedRoutesID := resource.ReplaceType(pbmesh.ComputedRoutesType, api1Service.Id)
|
||||
|
@ -553,11 +497,10 @@ func TestBuildImplicitDestinations(t *testing.T) {
|
|||
switch {
|
||||
case resource.ReferenceOrIDMatch(api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: api1Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api1Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{api1Identity}
|
||||
}
|
||||
}),
|
||||
|
@ -570,11 +513,10 @@ func TestBuildImplicitDestinations(t *testing.T) {
|
|||
switch {
|
||||
case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: api2Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api2Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{api2Identity}
|
||||
}
|
||||
}),
|
||||
|
@ -583,7 +525,7 @@ func TestBuildImplicitDestinations(t *testing.T) {
|
|||
|
||||
destination3 := &intermediate.Destination{
|
||||
Explicit: &pbmesh.Destination{
|
||||
DestinationRef: resource.Reference(api1Endpoints.Id, ""),
|
||||
DestinationRef: resource.Reference(api1Service.Id, ""),
|
||||
DestinationPort: "tcp",
|
||||
Datacenter: "dc1",
|
||||
ListenAddr: &pbmesh.Destination_IpPort{
|
||||
|
@ -595,11 +537,10 @@ func TestBuildImplicitDestinations(t *testing.T) {
|
|||
switch {
|
||||
case resource.ReferenceOrIDMatch(api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp":
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: api1Endpoints.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api1Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = endpointsData
|
||||
details.IdentityRefs = []*pbresource.Reference{api1Identity}
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -1,250 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
"github.com/hashicorp/consul/internal/resource/mappers/bimapper"
|
||||
"github.com/hashicorp/consul/internal/resource/mappers/selectiontracker"
|
||||
"github.com/hashicorp/consul/internal/storage"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
)
|
||||
|
||||
type Cache struct {
|
||||
// computedRoutes keeps track of computed routes IDs to service references it applies to.
|
||||
computedRoutes *bimapper.Mapper
|
||||
|
||||
// identities keeps track of which identity a workload is mapped to.
|
||||
identities *bimapper.Mapper
|
||||
|
||||
// computedDestinations keeps track of the computed explicit destinations IDs to service references that are
|
||||
// referenced in that resource.
|
||||
computedDestinations *bimapper.Mapper
|
||||
|
||||
// serviceSelectorTracker keeps track of which workload selectors a service is currently using.
|
||||
serviceSelectorTracker *selectiontracker.WorkloadSelectionTracker
|
||||
}
|
||||
|
||||
func New() *Cache {
|
||||
return &Cache{
|
||||
computedRoutes: bimapper.New(pbmesh.ComputedRoutesType, pbcatalog.ServiceType),
|
||||
identities: bimapper.New(pbcatalog.WorkloadType, pbauth.WorkloadIdentityType),
|
||||
computedDestinations: bimapper.New(pbmesh.ComputedExplicitDestinationsType, pbcatalog.ServiceType),
|
||||
serviceSelectorTracker: selectiontracker.New(),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) TrackComputedDestinations(computedDestinations *types.DecodedComputedDestinations) {
|
||||
var serviceRefs []resource.ReferenceOrID
|
||||
|
||||
for _, dest := range computedDestinations.Data.Destinations {
|
||||
serviceRefs = append(serviceRefs, dest.DestinationRef)
|
||||
}
|
||||
|
||||
c.computedDestinations.TrackItem(computedDestinations.Resource.Id, serviceRefs)
|
||||
}
|
||||
|
||||
func (c *Cache) UntrackComputedDestinations(computedDestinationsID *pbresource.ID) {
|
||||
c.computedDestinations.UntrackItem(computedDestinationsID)
|
||||
}
|
||||
|
||||
func (c *Cache) UntrackComputedRoutes(computedRoutesID *pbresource.ID) {
|
||||
c.computedRoutes.UntrackItem(computedRoutesID)
|
||||
}
|
||||
|
||||
func (c *Cache) TrackWorkload(workload *types.DecodedWorkload) {
|
||||
identityID := &pbresource.ID{
|
||||
Name: workload.GetData().Identity,
|
||||
Tenancy: workload.GetResource().Id.Tenancy,
|
||||
Type: pbauth.WorkloadIdentityType,
|
||||
}
|
||||
c.identities.TrackItem(workload.GetResource().GetId(), []resource.ReferenceOrID{identityID})
|
||||
}
|
||||
|
||||
// UntrackWorkload removes tracking for the given workload ID.
|
||||
func (c *Cache) UntrackWorkload(wID *pbresource.ID) {
|
||||
c.identities.UntrackItem(wID)
|
||||
}
|
||||
|
||||
func (c *Cache) ComputedDestinationsByService(id resource.ReferenceOrID) []*pbresource.ID {
|
||||
return c.computedDestinations.ItemIDsForLink(id)
|
||||
}
|
||||
|
||||
func (c *Cache) trackComputedRoutes(computedRoutes *types.DecodedComputedRoutes) {
|
||||
var serviceRefs []resource.ReferenceOrID
|
||||
|
||||
for _, pcr := range computedRoutes.Data.PortedConfigs {
|
||||
for _, details := range pcr.Targets {
|
||||
serviceRefs = append(serviceRefs, details.BackendRef.Ref)
|
||||
}
|
||||
}
|
||||
|
||||
c.computedRoutes.TrackItem(computedRoutes.Resource.Id, serviceRefs)
|
||||
}
|
||||
|
||||
func (c *Cache) computedRoutesByService(id resource.ReferenceOrID) []*pbresource.ID {
|
||||
return c.computedRoutes.ItemIDsForLink(id)
|
||||
}
|
||||
|
||||
func (c *Cache) WorkloadsByWorkloadIdentity(id *pbresource.ID) []*pbresource.ID {
|
||||
return c.identities.ItemIDsForLink(id)
|
||||
}
|
||||
|
||||
func (c *Cache) ServicesForWorkload(id *pbresource.ID) []*pbresource.ID {
|
||||
return c.serviceSelectorTracker.GetIDsForWorkload(id)
|
||||
}
|
||||
|
||||
func (c *Cache) UntrackService(id *pbresource.ID) {
|
||||
c.serviceSelectorTracker.UntrackID(id)
|
||||
}
|
||||
|
||||
func (c *Cache) MapComputedRoutes(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) {
|
||||
computedRoutes, err := resource.Decode[*pbmesh.ComputedRoutes](res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ids, err := c.mapComputedRoutesToProxyStateTemplate(ctx, rt, res.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.trackComputedRoutes(computedRoutes)
|
||||
|
||||
return controller.MakeRequests(pbmesh.ProxyStateTemplateType, ids), nil
|
||||
}
|
||||
|
||||
func (c *Cache) mapComputedRoutesToProxyStateTemplate(ctx context.Context, rt controller.Runtime, computedRoutesID *pbresource.ID) ([]*pbresource.ID, error) {
|
||||
// Each Destination gets a single ComputedRoutes.
|
||||
serviceID := resource.ReplaceType(pbcatalog.ServiceType, computedRoutesID)
|
||||
serviceRef := resource.Reference(serviceID, "")
|
||||
|
||||
return c.mapServiceThroughDestinations(ctx, rt, serviceRef)
|
||||
}
|
||||
|
||||
func (c *Cache) TrackService(svc *types.DecodedService) {
|
||||
c.serviceSelectorTracker.TrackIDForSelector(svc.Resource.GetId(), svc.GetData().GetWorkloads())
|
||||
}
|
||||
|
||||
func (c *Cache) MapService(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) {
|
||||
// Record workload selector in the cache every time we see an event for a service.
|
||||
decodedService, err := resource.Decode[*pbcatalog.Service](res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.TrackService(decodedService)
|
||||
|
||||
serviceRef := resource.Reference(res.Id, "")
|
||||
|
||||
pstIDs, err := c.mapServiceThroughDestinations(ctx, rt, serviceRef)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Now walk the mesh configuration information backwards because
|
||||
// we need to find any PST that needs to DISCOVER endpoints for this
|
||||
// service as a part of mesh configuration and traffic routing.
|
||||
|
||||
// Find all ComputedRoutes that reference this service.
|
||||
routeIDs := c.computedRoutesByService(serviceRef)
|
||||
for _, routeID := range routeIDs {
|
||||
// Find all Upstreams that reference a Service aligned with this ComputedRoutes.
|
||||
// Afterwards, find all Workloads selected by the Upstreams, and align a PST with those.
|
||||
ids, err := c.mapComputedRoutesToProxyStateTemplate(ctx, rt, routeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pstIDs = append(pstIDs, ids...)
|
||||
}
|
||||
|
||||
return controller.MakeRequests(pbmesh.ProxyStateTemplateType, pstIDs), nil
|
||||
}
|
||||
|
||||
// mapServiceThroughDestinations takes an explicit
|
||||
// Service and traverses back through Destinations to Workloads to
|
||||
// ProxyStateTemplates.
|
||||
//
|
||||
// This is in a separate function so it can be chained for more complicated
|
||||
// relationships.
|
||||
func (c *Cache) mapServiceThroughDestinations(
|
||||
ctx context.Context,
|
||||
rt controller.Runtime,
|
||||
serviceRef *pbresource.Reference,
|
||||
) ([]*pbresource.ID, error) {
|
||||
|
||||
// The relationship is:
|
||||
//
|
||||
// - PST (replace type) Workload
|
||||
// - Workload (name-aligned) ComputedDestinations
|
||||
// - ComputedDestinations (contains) Service
|
||||
//
|
||||
// When we wake up for Service we should:
|
||||
//
|
||||
// - look up computed destinations for the service
|
||||
// - rewrite computed destination types to PST
|
||||
|
||||
var pstIDs []*pbresource.ID
|
||||
|
||||
// Get all source proxies if they're referenced in any explicit destinations from computed destinations (name-aligned with workload/PST).
|
||||
sources := c.ComputedDestinationsByService(serviceRef)
|
||||
for _, cdID := range sources {
|
||||
pstIDs = append(pstIDs, resource.ReplaceType(pbmesh.ProxyStateTemplateType, cdID))
|
||||
}
|
||||
|
||||
// TODO(v2): remove this after we can do proper performant implicit upstream determination
|
||||
//
|
||||
// TODO(rb): shouldn't this instead list all Workloads that have a mesh port?
|
||||
allIDs, err := c.listAllProxyStateTemplatesTemporarily(ctx, rt, serviceRef.Tenancy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pstIDs = append(pstIDs, allIDs...)
|
||||
|
||||
return pstIDs, nil
|
||||
}
|
||||
|
||||
func (c *Cache) listAllProxyStateTemplatesTemporarily(ctx context.Context, rt controller.Runtime, tenancy *pbresource.Tenancy) ([]*pbresource.ID, error) {
|
||||
// todo (ishustava): this is a stub for now until we implement implicit destinations.
|
||||
// For tproxy, we generate requests for all proxy states in the cluster.
|
||||
// This will generate duplicate events for proxies already added above,
|
||||
// however, we expect that the controller runtime will de-dup for us.
|
||||
rsp, err := rt.Client.List(ctx, &pbresource.ListRequest{
|
||||
Type: pbmesh.ProxyStateTemplateType,
|
||||
Tenancy: &pbresource.Tenancy{
|
||||
Namespace: storage.Wildcard,
|
||||
Partition: tenancy.Partition,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*pbresource.ID, 0, len(rsp.Resources))
|
||||
for _, r := range rsp.Resources {
|
||||
result = append(result, r.Id)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *Cache) MapComputedTrafficPermissions(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) {
|
||||
var ctp pbauth.ComputedTrafficPermissions
|
||||
err := res.Data.UnmarshalTo(&ctp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
workloadIdentityID := resource.ReplaceType(pbauth.WorkloadIdentityType, res.Id)
|
||||
ids := c.WorkloadsByWorkloadIdentity(workloadIdentityID)
|
||||
|
||||
return controller.MakeRequests(pbmesh.ProxyStateTemplateType, ids), nil
|
||||
}
|
|
@ -1,459 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing"
|
||||
"github.com/hashicorp/consul/internal/catalog"
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/routestest"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
"github.com/hashicorp/consul/proto/private/prototest"
|
||||
)
|
||||
|
||||
func TestIdentities(t *testing.T) {
|
||||
resourcetest.RunWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
cache := New()
|
||||
|
||||
identityID1 := resourcetest.Resource(pbauth.WorkloadIdentityType, "workload-identity-1").
|
||||
WithTenancy(tenancy).ID()
|
||||
identityID2 := resourcetest.Resource(pbauth.WorkloadIdentityType, "workload-identity-2").
|
||||
WithTenancy(tenancy).ID()
|
||||
|
||||
w1 := resourcetest.Resource(pbcatalog.WorkloadType, "service-workload-1").
|
||||
WithData(t, &pbcatalog.Workload{
|
||||
Identity: identityID1.Name,
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Build()
|
||||
decW1 := resourcetest.MustDecode[*pbcatalog.Workload](t, w1)
|
||||
w2 := resourcetest.Resource(pbcatalog.WorkloadType, "service-workload-2").
|
||||
WithData(t, &pbcatalog.Workload{
|
||||
Identity: identityID2.Name,
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Build()
|
||||
decW2 := resourcetest.MustDecode[*pbcatalog.Workload](t, w2)
|
||||
|
||||
// Empty cache
|
||||
require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID1))
|
||||
require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID2))
|
||||
|
||||
// Insert value and fetch it.
|
||||
cache.TrackWorkload(decW1)
|
||||
require.Equal(t, []*pbresource.ID{w1.Id}, cache.WorkloadsByWorkloadIdentity(identityID1))
|
||||
require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID2))
|
||||
|
||||
// Insert another value referencing the same identity.
|
||||
decW2.GetData().Identity = identityID1.Name
|
||||
cache.TrackWorkload(decW2)
|
||||
require.ElementsMatch(t, []*pbresource.ID{w1.Id, w2.Id}, cache.WorkloadsByWorkloadIdentity(identityID1))
|
||||
require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID2))
|
||||
|
||||
// Now workload 1 uses identity 2
|
||||
decW1.GetData().Identity = identityID2.Name
|
||||
cache.TrackWorkload(decW1)
|
||||
require.Equal(t, []*pbresource.ID{w1.Id}, cache.WorkloadsByWorkloadIdentity(identityID2))
|
||||
require.Equal(t, []*pbresource.ID{w2.Id}, cache.WorkloadsByWorkloadIdentity(identityID1))
|
||||
|
||||
// Untrack workload 2
|
||||
cache.UntrackWorkload(w2.Id)
|
||||
require.Equal(t, []*pbresource.ID{w1.Id}, cache.WorkloadsByWorkloadIdentity(identityID2))
|
||||
require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID1))
|
||||
|
||||
// Untrack workload 1
|
||||
cache.UntrackWorkload(w1.Id)
|
||||
require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID2))
|
||||
require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID1))
|
||||
}, t)
|
||||
}
|
||||
|
||||
func TestMapComputedTrafficPermissions(t *testing.T) {
|
||||
resourcetest.RunWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
client := svctest.NewResourceServiceBuilder().
|
||||
WithRegisterFns(types.Register, catalog.RegisterTypes).
|
||||
Run(t)
|
||||
|
||||
ctp := resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, "workload-identity-1").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, &pbauth.ComputedTrafficPermissions{}).
|
||||
Build()
|
||||
|
||||
c := New()
|
||||
|
||||
// Empty results when the cache isn't populated.
|
||||
requests, err := c.MapComputedTrafficPermissions(context.Background(), controller.Runtime{Client: client}, ctp)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, requests, 0)
|
||||
|
||||
identityID1 := resourcetest.Resource(pbauth.WorkloadIdentityType, "workload-identity-1").
|
||||
WithTenancy(tenancy).ID()
|
||||
|
||||
w1 := resourcetest.Resource(pbcatalog.WorkloadType, "service-workload-1").
|
||||
WithData(t, &pbcatalog.Workload{
|
||||
Identity: identityID1.Name,
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Build()
|
||||
decW1 := resourcetest.MustDecode[*pbcatalog.Workload](t, w1)
|
||||
w2 := resourcetest.Resource(pbcatalog.WorkloadType, "service-workload-2").
|
||||
WithData(t, &pbcatalog.Workload{
|
||||
Identity: identityID1.Name,
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Build()
|
||||
decW2 := resourcetest.MustDecode[*pbcatalog.Workload](t, w2)
|
||||
|
||||
c.TrackWorkload(decW1)
|
||||
|
||||
// Empty results when the cache isn't populated.
|
||||
requests, err = c.MapComputedTrafficPermissions(context.Background(), controller.Runtime{Client: client}, ctp)
|
||||
require.NoError(t, err)
|
||||
prototest.AssertElementsMatch(t,
|
||||
[]controller.Request{{ID: resource.ReplaceType(pbmesh.ProxyStateTemplateType, w1.Id)}}, requests)
|
||||
|
||||
c.TrackWorkload(decW2)
|
||||
|
||||
// Empty results when the cache isn't populated.
|
||||
requests, err = c.MapComputedTrafficPermissions(context.Background(), controller.Runtime{Client: client}, ctp)
|
||||
require.NoError(t, err)
|
||||
prototest.AssertElementsMatch(t, []controller.Request{
|
||||
{ID: resource.ReplaceType(pbmesh.ProxyStateTemplateType, w1.Id)},
|
||||
{ID: resource.ReplaceType(pbmesh.ProxyStateTemplateType, w2.Id)},
|
||||
}, requests)
|
||||
}, t)
|
||||
}
|
||||
|
||||
func TestUnified_AllMappingsToProxyStateTemplate(t *testing.T) {
|
||||
resourcetest.RunWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
var (
|
||||
cache = New()
|
||||
client = svctest.NewResourceServiceBuilder().
|
||||
WithRegisterFns(types.Register, catalog.RegisterTypes).
|
||||
Run(t)
|
||||
)
|
||||
|
||||
anyServiceData := &pbcatalog.Service{
|
||||
Workloads: &pbcatalog.WorkloadSelector{
|
||||
Prefixes: []string{"src-workload"},
|
||||
},
|
||||
Ports: []*pbcatalog.ServicePort{
|
||||
{
|
||||
TargetPort: "tcp1",
|
||||
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
||||
},
|
||||
{
|
||||
TargetPort: "tcp2",
|
||||
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
||||
},
|
||||
{
|
||||
TargetPort: "mesh",
|
||||
Protocol: pbcatalog.Protocol_PROTOCOL_MESH,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// The thing we link through Destinations.
|
||||
destService := resourcetest.Resource(pbcatalog.ServiceType, "web").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, anyServiceData).
|
||||
Build()
|
||||
destServiceRef := resource.Reference(destService.Id, "")
|
||||
|
||||
// The thing we reach through the mesh config.
|
||||
targetService := resourcetest.Resource(pbcatalog.ServiceType, "db").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, anyServiceData).
|
||||
Build()
|
||||
targetServiceRef := resource.Reference(targetService.Id, "")
|
||||
|
||||
backupTargetService := resourcetest.Resource(pbcatalog.ServiceType, "db-backup").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, anyServiceData).
|
||||
Build()
|
||||
backupTargetServiceRef := resource.Reference(backupTargetService.Id, "")
|
||||
|
||||
// The way we make 'web' actually route traffic to 'db'.
|
||||
tcpRoute := resourcetest.Resource(pbmesh.TCPRouteType, "tcp-route").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, &pbmesh.TCPRoute{
|
||||
ParentRefs: []*pbmesh.ParentReference{{
|
||||
Ref: destServiceRef,
|
||||
}},
|
||||
Rules: []*pbmesh.TCPRouteRule{{
|
||||
BackendRefs: []*pbmesh.TCPBackendRef{{
|
||||
BackendRef: &pbmesh.BackendReference{
|
||||
Ref: targetServiceRef,
|
||||
},
|
||||
}},
|
||||
}},
|
||||
}).
|
||||
Build()
|
||||
|
||||
failoverPolicy := &pbcatalog.FailoverPolicy{
|
||||
Config: &pbcatalog.FailoverConfig{
|
||||
Destinations: []*pbcatalog.FailoverDestination{{
|
||||
Ref: backupTargetServiceRef,
|
||||
}},
|
||||
},
|
||||
}
|
||||
simiplifiedFailoverPolicy := catalog.SimplifyFailoverPolicy(anyServiceData, failoverPolicy)
|
||||
computedFailoverPolicy := resourcetest.ResourceID(resource.ReplaceType(pbcatalog.ComputedFailoverPolicyType, targetService.Id)).
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, &pbcatalog.ComputedFailoverPolicy{
|
||||
PortConfigs: simiplifiedFailoverPolicy.PortConfigs,
|
||||
}).
|
||||
Build()
|
||||
webRoutes := routestest.BuildComputedRoutes(t, resource.ReplaceType(pbmesh.ComputedRoutesType, destService.Id),
|
||||
resourcetest.MustDecode[*pbcatalog.Service](t, destService),
|
||||
resourcetest.MustDecode[*pbcatalog.Service](t, targetService),
|
||||
resourcetest.MustDecode[*pbcatalog.Service](t, backupTargetService),
|
||||
resourcetest.MustDecode[*pbmesh.TCPRoute](t, tcpRoute),
|
||||
resourcetest.MustDecode[*pbcatalog.ComputedFailoverPolicy](t, computedFailoverPolicy),
|
||||
)
|
||||
|
||||
var (
|
||||
sourceProxy1 = newID(pbmesh.ProxyStateTemplateType, "src-workload-1", tenancy)
|
||||
sourceProxy2 = newID(pbmesh.ProxyStateTemplateType, "src-workload-2", tenancy)
|
||||
sourceProxy3 = newID(pbmesh.ProxyStateTemplateType, "src-workload-3", tenancy)
|
||||
sourceProxy4 = newID(pbmesh.ProxyStateTemplateType, "src-workload-4", tenancy)
|
||||
sourceProxy5 = newID(pbmesh.ProxyStateTemplateType, "src-workload-5", tenancy)
|
||||
sourceProxy6 = newID(pbmesh.ProxyStateTemplateType, "src-workload-6", tenancy)
|
||||
)
|
||||
|
||||
compDestProxy1 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy1.Name).
|
||||
WithData(t, &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
{
|
||||
DestinationRef: destServiceRef,
|
||||
DestinationPort: "tcp1",
|
||||
},
|
||||
},
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Build()
|
||||
|
||||
compDestProxy2 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy2.Name).
|
||||
WithData(t, &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
{
|
||||
DestinationRef: destServiceRef,
|
||||
DestinationPort: "tcp1",
|
||||
},
|
||||
},
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Build()
|
||||
|
||||
compDestProxy3 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy3.Name).
|
||||
WithData(t, &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
{
|
||||
DestinationRef: destServiceRef,
|
||||
DestinationPort: "tcp2",
|
||||
},
|
||||
},
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Build()
|
||||
|
||||
compDestProxy4 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy4.Name).
|
||||
WithData(t, &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
{
|
||||
DestinationRef: destServiceRef,
|
||||
DestinationPort: "tcp2",
|
||||
},
|
||||
},
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Build()
|
||||
|
||||
compDestProxy5 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy5.Name).
|
||||
WithData(t, &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
{
|
||||
DestinationRef: destServiceRef,
|
||||
DestinationPort: "mesh",
|
||||
},
|
||||
},
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Build()
|
||||
|
||||
compDestProxy6 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy6.Name).
|
||||
WithData(t, &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
{
|
||||
DestinationRef: destServiceRef,
|
||||
DestinationPort: "mesh",
|
||||
},
|
||||
},
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Build()
|
||||
|
||||
cache.trackComputedRoutes(webRoutes)
|
||||
cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy1))
|
||||
cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy2))
|
||||
cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy3))
|
||||
cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy4))
|
||||
cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy5))
|
||||
cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy6))
|
||||
|
||||
t.Run(resourcetest.AppendTenancyInfoSubtest(t.Name(), "Service", tenancy), func(t *testing.T) {
|
||||
t.Run("map dest service", func(t *testing.T) {
|
||||
requests, err := cache.MapService(
|
||||
context.Background(),
|
||||
controller.Runtime{Client: client},
|
||||
destService,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Only wake up things with dest as an upstream.
|
||||
expRequests := []controller.Request{
|
||||
{ID: sourceProxy1},
|
||||
{ID: sourceProxy2},
|
||||
{ID: sourceProxy3},
|
||||
{ID: sourceProxy4},
|
||||
{ID: sourceProxy5},
|
||||
{ID: sourceProxy6},
|
||||
}
|
||||
|
||||
prototest.AssertElementsMatch(t, expRequests, requests)
|
||||
|
||||
// Check that service's workload selector is tracked.
|
||||
prototest.AssertElementsMatch(t,
|
||||
[]*pbresource.ID{destService.Id},
|
||||
cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy1)))
|
||||
prototest.AssertElementsMatch(t,
|
||||
[]*pbresource.ID{destService.Id},
|
||||
cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy2)))
|
||||
prototest.AssertElementsMatch(t,
|
||||
[]*pbresource.ID{destService.Id},
|
||||
cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy3)))
|
||||
prototest.AssertElementsMatch(t,
|
||||
[]*pbresource.ID{destService.Id},
|
||||
cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy4)))
|
||||
prototest.AssertElementsMatch(t,
|
||||
[]*pbresource.ID{destService.Id},
|
||||
cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy5)))
|
||||
prototest.AssertElementsMatch(t,
|
||||
[]*pbresource.ID{destService.Id},
|
||||
cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy6)))
|
||||
})
|
||||
|
||||
t.Run("map target endpoints (TCPRoute)", func(t *testing.T) {
|
||||
requests, err := cache.MapService(
|
||||
context.Background(),
|
||||
controller.Runtime{Client: client},
|
||||
targetService,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
requests = testDeduplicateRequests(requests)
|
||||
|
||||
expRequests := []controller.Request{
|
||||
// Wakeup things that have destService as a destination b/c of the TCPRoute reference.
|
||||
{ID: sourceProxy1},
|
||||
{ID: sourceProxy2},
|
||||
{ID: sourceProxy3},
|
||||
{ID: sourceProxy4},
|
||||
{ID: sourceProxy5},
|
||||
{ID: sourceProxy6},
|
||||
}
|
||||
|
||||
prototest.AssertElementsMatch(t, expRequests, requests)
|
||||
})
|
||||
|
||||
t.Run("map backup target endpoints (FailoverPolicy)", func(t *testing.T) {
|
||||
requests, err := cache.MapService(
|
||||
context.Background(),
|
||||
controller.Runtime{Client: client},
|
||||
backupTargetService,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
requests = testDeduplicateRequests(requests)
|
||||
|
||||
expRequests := []controller.Request{
|
||||
// Wakeup things that have destService as a destination b/c of the FailoverPolicy reference.
|
||||
{ID: sourceProxy1},
|
||||
{ID: sourceProxy2},
|
||||
{ID: sourceProxy3},
|
||||
{ID: sourceProxy4},
|
||||
{ID: sourceProxy5},
|
||||
{ID: sourceProxy6},
|
||||
}
|
||||
|
||||
prototest.AssertElementsMatch(t, expRequests, requests)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run(resourcetest.AppendTenancyInfoSubtest(t.Name(), "ComputedRoutes", tenancy), func(t *testing.T) {
|
||||
t.Run("map web routes", func(t *testing.T) {
|
||||
requests, err := cache.MapComputedRoutes(
|
||||
context.Background(),
|
||||
controller.Runtime{Client: client},
|
||||
webRoutes.Resource,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Only wake up things with dest as an upstream.
|
||||
expRequests := []controller.Request{
|
||||
{ID: sourceProxy1},
|
||||
{ID: sourceProxy2},
|
||||
{ID: sourceProxy3},
|
||||
{ID: sourceProxy4},
|
||||
{ID: sourceProxy5},
|
||||
{ID: sourceProxy6},
|
||||
}
|
||||
|
||||
prototest.AssertElementsMatch(t, expRequests, requests)
|
||||
})
|
||||
})
|
||||
}, t)
|
||||
}
|
||||
|
||||
func newID(typ *pbresource.Type, name string, tenancy *pbresource.Tenancy) *pbresource.ID {
|
||||
return &pbresource.ID{
|
||||
Type: typ,
|
||||
Tenancy: tenancy,
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func testDeduplicateRequests(reqs []controller.Request) []controller.Request {
|
||||
type resID struct {
|
||||
resource.ReferenceKey
|
||||
UID string
|
||||
}
|
||||
|
||||
out := make([]controller.Request, 0, len(reqs))
|
||||
seen := make(map[resID]struct{})
|
||||
|
||||
for _, req := range reqs {
|
||||
rid := resID{
|
||||
ReferenceKey: resource.NewReferenceKey(req.ID),
|
||||
UID: req.ID.Uid,
|
||||
}
|
||||
if _, ok := seen[rid]; !ok {
|
||||
out = append(out, req)
|
||||
seen[rid] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
|
@ -6,15 +6,14 @@ package sidecarproxy
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
"github.com/hashicorp/consul/internal/catalog/workloadselector"
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/controller/cache"
|
||||
"github.com/hashicorp/consul/internal/controller/dependency"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/builder"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/fetcher"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
|
@ -29,71 +28,86 @@ const ControllerName = "consul.io/sidecar-proxy-controller"
|
|||
type TrustDomainFetcher func() (string, error)
|
||||
|
||||
func Controller(
|
||||
cache *cache.Cache,
|
||||
trustDomainFetcher TrustDomainFetcher,
|
||||
dc string,
|
||||
defaultAllow bool,
|
||||
) *controller.Controller {
|
||||
if cache == nil || trustDomainFetcher == nil {
|
||||
panic("cache and trust domain fetcher are required")
|
||||
if trustDomainFetcher == nil {
|
||||
panic("trust domain fetcher is required")
|
||||
}
|
||||
|
||||
/*
|
||||
Workload <align> PST
|
||||
ComputedDestinations <align> PST(==Workload)
|
||||
ComputedDestinations <contain> Service(destinations)
|
||||
ComputedExplicitDestinations <align> PST(==Workload)
|
||||
ComputedExplicitDestinations <contain> Service(destinations)
|
||||
ComputedProxyConfiguration <align> PST(==Workload)
|
||||
ComputedRoutes <align> Service(upstream)
|
||||
ComputedRoutes <contain> Service(disco)
|
||||
ComputedTrafficPermissions <align> WorkloadIdentity
|
||||
Workload <contain> WorkloadIdentity
|
||||
ComputedImplicitDestinations <align> WorkloadIdentity
|
||||
ComputedImplicitDestinations <contain> Service(destinations)
|
||||
|
||||
These relationships then dictate the following reconcile logic.
|
||||
|
||||
controller: read workload for PST
|
||||
controller: read previous PST
|
||||
controller: read ComputedProxyConfiguration for Workload
|
||||
controller: read ComputedDestinations for workload to walk explicit upstreams
|
||||
controller: read ComputedExplicitDestinations for workload to walk explicit destinations
|
||||
controller: maybe read ComputedImplicitDestinations for workload.identity to walk implicit destinations
|
||||
controller: read ComputedTrafficPermissions for workload using workload.identity field.
|
||||
<EXPLICIT-for-each>
|
||||
<EXPLICIT_OR_IMPLICIT-for-each>
|
||||
fetcher: read Service(Destination)
|
||||
fetcher: read ComputedRoutes
|
||||
<TARGET-for-each>
|
||||
fetcher: read ServiceEndpoints
|
||||
fetcher: read Service
|
||||
</TARGET-for-each>
|
||||
</EXPLICIT-for-each>
|
||||
<IMPLICIT>
|
||||
fetcher: list ALL ComputedRoutes
|
||||
<CR-for-each>
|
||||
fetcher: read Service(upstream)
|
||||
<TARGET-for-each>
|
||||
fetcher: read ServiceEndpoints
|
||||
</TARGET-for-each>
|
||||
</CR-for-each>
|
||||
</IMPLICIT>
|
||||
</EXPLICIT_OR_IMPLICIT-for-each>
|
||||
*/
|
||||
|
||||
/*
|
||||
Which means for equivalence, the following mapper relationships should exist:
|
||||
|
||||
Service: find destinations with Service; Recurse(ComputedDestinations);
|
||||
Service: find destinations with Service; Recurse(ComputedXDestinations);
|
||||
find ComputedRoutes with this in a Target or FailoverConfig; Recurse(ComputedRoutes)
|
||||
ComputedDestinations: replace type CED=>PST
|
||||
ComputedExplicitDestinations: replace type CED=>PST
|
||||
ComputedImplicitDestinations: replace type CID=>WI; find workload with this identity; replace type WRK=>PST
|
||||
ComputedProxyConfiguration: replace type CPC=>PST
|
||||
ComputedRoutes: CR=>Service; find destinations with Service; Recurse(Destinations)
|
||||
[implicit/temp]: trigger all
|
||||
ComputedTrafficPermissions: find workloads in cache stored for this CTP=Workload, workloads=>PST reconcile requests
|
||||
*/
|
||||
|
||||
// TODO(rb): ultimately needs some form of BoundReferences
|
||||
return controller.NewController(ControllerName, pbmesh.ProxyStateTemplateType).
|
||||
WithWatch(pbcatalog.ServiceType, cache.MapService).
|
||||
WithWatch(pbcatalog.WorkloadType, dependency.ReplaceType(pbmesh.ProxyStateTemplateType)).
|
||||
WithWatch(pbmesh.ComputedExplicitDestinationsType, dependency.ReplaceType(pbmesh.ProxyStateTemplateType)).
|
||||
WithWatch(pbmesh.ComputedProxyConfigurationType, dependency.ReplaceType(pbmesh.ProxyStateTemplateType)).
|
||||
WithWatch(pbmesh.ComputedRoutesType, cache.MapComputedRoutes).
|
||||
WithWatch(pbauth.ComputedTrafficPermissionsType, cache.MapComputedTrafficPermissions).
|
||||
WithWatch(pbcatalog.ServiceType,
|
||||
MapService,
|
||||
serviceByWorkloadIdentityIndex,
|
||||
workloadselector.Index[*pbcatalog.Service](selectedWorkloadsIndexName),
|
||||
).
|
||||
WithWatch(pbcatalog.WorkloadType,
|
||||
dependency.ReplaceType(pbmesh.ProxyStateTemplateType),
|
||||
workloadByWorkloadIdentityIndex,
|
||||
).
|
||||
WithWatch(pbmesh.ComputedExplicitDestinationsType,
|
||||
dependency.ReplaceType(pbmesh.ProxyStateTemplateType),
|
||||
computedExplicitDestinationsByServiceIndex,
|
||||
).
|
||||
WithWatch(pbmesh.ComputedImplicitDestinationsType,
|
||||
MapComputedImplicitDestinations,
|
||||
computedImplicitDestinationsByServiceIndex,
|
||||
).
|
||||
WithWatch(pbmesh.ComputedProxyConfigurationType,
|
||||
dependency.ReplaceType(pbmesh.ProxyStateTemplateType),
|
||||
).
|
||||
WithWatch(pbmesh.ComputedRoutesType,
|
||||
MapComputedRoutes,
|
||||
computedRoutesByBackendServiceIndex,
|
||||
).
|
||||
WithWatch(pbauth.ComputedTrafficPermissionsType,
|
||||
MapComputedTrafficPermissions,
|
||||
).
|
||||
WithReconciler(&reconciler{
|
||||
cache: cache,
|
||||
getTrustDomain: trustDomainFetcher,
|
||||
dc: dc,
|
||||
defaultAllow: defaultAllow,
|
||||
|
@ -101,7 +115,6 @@ func Controller(
|
|||
}
|
||||
|
||||
type reconciler struct {
|
||||
cache *cache.Cache
|
||||
getTrustDomain TrustDomainFetcher
|
||||
defaultAllow bool
|
||||
dc string
|
||||
|
@ -112,12 +125,9 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c
|
|||
|
||||
rt.Logger.Trace("reconciling proxy state template")
|
||||
|
||||
// Instantiate a data fetcher to fetch all reconciliation data.
|
||||
dataFetcher := fetcher.New(rt.Client, r.cache)
|
||||
|
||||
// Check if the workload exists.
|
||||
workloadID := resource.ReplaceType(pbcatalog.WorkloadType, req.ID)
|
||||
workload, err := dataFetcher.FetchWorkload(ctx, workloadID)
|
||||
workload, err := cache.GetDecoded[*pbcatalog.Workload](rt.Cache, pbcatalog.WorkloadType, "id", workloadID)
|
||||
if err != nil {
|
||||
rt.Logger.Error("error reading the associated workload", "error", err)
|
||||
return err
|
||||
|
@ -136,7 +146,7 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c
|
|||
return nil
|
||||
}
|
||||
|
||||
proxyStateTemplate, err := dataFetcher.FetchProxyStateTemplate(ctx, req.ID)
|
||||
proxyStateTemplate, err := cache.GetDecoded[*pbmesh.ProxyStateTemplate](rt.Cache, pbmesh.ProxyStateTemplateType, "id", req.ID)
|
||||
if err != nil {
|
||||
rt.Logger.Error("error reading proxy state template", "error", err)
|
||||
return nil
|
||||
|
@ -147,7 +157,7 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c
|
|||
rt.Logger.Trace("proxy state template for this workload doesn't yet exist; generating a new one")
|
||||
}
|
||||
|
||||
if !workload.GetData().IsMeshEnabled() {
|
||||
if !workload.GetData().IsMeshEnabled() || workload.Data.Identity == "" {
|
||||
// Skip non-mesh workloads.
|
||||
|
||||
// If there's existing proxy state template, delete it.
|
||||
|
@ -171,13 +181,20 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c
|
|||
}
|
||||
|
||||
// Fetch proxy configuration.
|
||||
proxyCfg, err := dataFetcher.FetchComputedProxyConfiguration(ctx, req.ID)
|
||||
cpcID := resource.ReplaceType(pbmesh.ComputedProxyConfigurationType, req.ID)
|
||||
proxyCfg, err := cache.GetDecoded[*pbmesh.ComputedProxyConfiguration](rt.Cache, pbmesh.ComputedProxyConfigurationType, "id", cpcID)
|
||||
if err != nil {
|
||||
rt.Logger.Error("error fetching proxy and merging proxy configurations", "error", err)
|
||||
return err
|
||||
}
|
||||
// note the proxyCfg may be nil
|
||||
|
||||
trafficPermissions, err := dataFetcher.FetchComputedTrafficPermissions(ctx, computedTrafficPermissionsIDFromWorkload(workload))
|
||||
ctpID := &pbresource.ID{
|
||||
Type: pbauth.ComputedTrafficPermissionsType,
|
||||
Name: workload.Data.Identity,
|
||||
Tenancy: workload.Resource.Id.Tenancy,
|
||||
}
|
||||
trafficPermissions, err := cache.GetDecoded[*pbauth.ComputedTrafficPermissions](rt.Cache, pbauth.ComputedTrafficPermissionsType, "id", ctpID)
|
||||
if err != nil {
|
||||
rt.Logger.Error("error fetching computed traffic permissions to compute proxy state template", "error", err)
|
||||
return err
|
||||
|
@ -188,7 +205,7 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c
|
|||
ctp = trafficPermissions.Data
|
||||
}
|
||||
|
||||
workloadPorts, err := r.workloadPortProtocolsFromService(ctx, dataFetcher, workload, rt.Logger)
|
||||
workloadPorts, err := workloadPortProtocolsFromService(rt, workload)
|
||||
if err != nil {
|
||||
rt.Logger.Error("error determining workload ports", "error", err)
|
||||
return err
|
||||
|
@ -196,24 +213,35 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c
|
|||
workloadDataWithInheritedPorts := proto.Clone(workload.Data).(*pbcatalog.Workload)
|
||||
workloadDataWithInheritedPorts.Ports = workloadPorts
|
||||
|
||||
b := builder.New(req.ID, identityRefFromWorkload(workload), trustDomain, r.dc, r.defaultAllow, proxyCfg.GetData()).
|
||||
workloadIdentityRef := &pbresource.Reference{
|
||||
Name: workload.Data.Identity,
|
||||
Tenancy: workload.Resource.Id.Tenancy,
|
||||
Type: pbauth.WorkloadIdentityType,
|
||||
}
|
||||
|
||||
b := builder.New(
|
||||
req.ID,
|
||||
workloadIdentityRef,
|
||||
trustDomain,
|
||||
r.dc,
|
||||
r.defaultAllow,
|
||||
proxyCfg.GetData(),
|
||||
).
|
||||
BuildLocalApp(workloadDataWithInheritedPorts, ctp)
|
||||
|
||||
// Get all destinationsData.
|
||||
destinationsData, err := dataFetcher.FetchComputedExplicitDestinationsData(ctx, req.ID, proxyCfg.GetData())
|
||||
if err != nil {
|
||||
rt.Logger.Error("error fetching explicit destinations for this proxy", "error", err)
|
||||
return err
|
||||
mgwMode := pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_NONE
|
||||
if dynamicCfg := proxyCfg.GetData().GetDynamicConfig(); dynamicCfg != nil {
|
||||
mgwMode = dynamicCfg.GetMeshGatewayMode()
|
||||
}
|
||||
|
||||
if proxyCfg.GetData() != nil && proxyCfg.GetData().IsTransparentProxy() {
|
||||
rt.Logger.Trace("transparent proxy is enabled; fetching implicit destinations")
|
||||
destinationsData, err = dataFetcher.FetchImplicitDestinationsData(ctx, req.ID, destinationsData)
|
||||
// Get all destinationsData.
|
||||
destinationsData, err := FetchUnifiedDestinationsData(
|
||||
ctx, rt, workload, mgwMode,
|
||||
proxyCfg.GetData().IsTransparentProxy())
|
||||
if err != nil {
|
||||
rt.Logger.Error("error fetching implicit destinations for this proxy", "error", err)
|
||||
rt.Logger.Error("error fetching destinations for this proxy", "error", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
b.BuildDestinations(destinationsData)
|
||||
|
||||
|
@ -247,32 +275,13 @@ func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *reconciler) workloadPortProtocolsFromService(
|
||||
ctx context.Context,
|
||||
fetcher *fetcher.Fetcher,
|
||||
workload *types.DecodedWorkload,
|
||||
logger hclog.Logger,
|
||||
) (map[string]*pbcatalog.WorkloadPort, error) {
|
||||
func workloadPortProtocolsFromService(rt controller.Runtime, workload *types.DecodedWorkload) (map[string]*pbcatalog.WorkloadPort, error) {
|
||||
// Fetch all services for this workload.
|
||||
serviceIDs := r.cache.ServicesForWorkload(workload.GetResource().GetId())
|
||||
|
||||
var services []*types.DecodedService
|
||||
|
||||
for _, serviceID := range serviceIDs {
|
||||
svc, err := fetcher.FetchService(ctx, serviceID)
|
||||
services, err := cache.ParentsDecoded[*pbcatalog.Service](rt.Cache, pbcatalog.ServiceType, selectedWorkloadsIndexName, workload.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If service is not found, we should untrack it.
|
||||
if svc == nil {
|
||||
r.cache.UntrackService(serviceID)
|
||||
continue
|
||||
}
|
||||
|
||||
services = append(services, svc)
|
||||
}
|
||||
|
||||
// Now walk through all workload ports.
|
||||
// For ports that don't have a protocol explicitly specified, inherit it from the service.
|
||||
|
||||
|
@ -286,8 +295,8 @@ func (r *reconciler) workloadPortProtocolsFromService(
|
|||
}
|
||||
|
||||
// Check if we have any service IDs or fetched services.
|
||||
if len(serviceIDs) == 0 || len(services) == 0 {
|
||||
logger.Trace("found no services for this workload's port; using default TCP protocol", "port", portName)
|
||||
if len(services) == 0 {
|
||||
rt.Logger.Trace("found no services for this workload's port; using default TCP protocol", "port", portName)
|
||||
result[portName] = &pbcatalog.WorkloadPort{
|
||||
Port: port.GetPort(),
|
||||
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
||||
|
@ -299,7 +308,7 @@ func (r *reconciler) workloadPortProtocolsFromService(
|
|||
inheritedProtocol := pbcatalog.Protocol_PROTOCOL_UNSPECIFIED
|
||||
for _, svc := range services {
|
||||
// Find workload's port as the target port.
|
||||
svcPort := svc.GetData().FindTargetPort(portName)
|
||||
svcPort := svc.Data.FindTargetPort(portName)
|
||||
|
||||
// If this service doesn't select this port, go to the next service.
|
||||
if svcPort == nil {
|
||||
|
@ -312,7 +321,7 @@ func (r *reconciler) workloadPortProtocolsFromService(
|
|||
if inheritedProtocol != pbcatalog.Protocol_PROTOCOL_UNSPECIFIED &&
|
||||
svcPort.GetProtocol() != inheritedProtocol {
|
||||
|
||||
logger.Trace("found conflicting service protocols that select this workload port; using default TCP protocol", "port", portName)
|
||||
rt.Logger.Trace("found conflicting service protocols that select this workload port; using default TCP protocol", "port", portName)
|
||||
inheritedProtocol = pbcatalog.Protocol_PROTOCOL_TCP
|
||||
|
||||
// We won't check any remaining services as there's already a conflict.
|
||||
|
@ -324,7 +333,7 @@ func (r *reconciler) workloadPortProtocolsFromService(
|
|||
|
||||
// If after going through all services, we haven't found a protocol, use the default.
|
||||
if inheritedProtocol == pbcatalog.Protocol_PROTOCOL_UNSPECIFIED {
|
||||
logger.Trace("no services select this workload port; using default TCP protocol", "port", portName)
|
||||
rt.Logger.Trace("no services select this workload port; using default TCP protocol", "port", portName)
|
||||
result[portName] = &pbcatalog.WorkloadPort{
|
||||
Port: port.GetPort(),
|
||||
Protocol: pbcatalog.Protocol_PROTOCOL_TCP,
|
||||
|
@ -339,19 +348,3 @@ func (r *reconciler) workloadPortProtocolsFromService(
|
|||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func identityRefFromWorkload(w *types.DecodedWorkload) *pbresource.Reference {
|
||||
return &pbresource.Reference{
|
||||
Name: w.Data.Identity,
|
||||
Tenancy: w.Resource.Id.Tenancy,
|
||||
Type: pbauth.WorkloadIdentityType,
|
||||
}
|
||||
}
|
||||
|
||||
func computedTrafficPermissionsIDFromWorkload(w *types.DecodedWorkload) *pbresource.ID {
|
||||
return &pbresource.ID{
|
||||
Type: pbauth.ComputedTrafficPermissionsType,
|
||||
Name: w.Data.Identity,
|
||||
Tenancy: w.Resource.Id.Tenancy,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@ import (
|
|||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/routestest"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/builder"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/fetcher"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
|
@ -37,11 +35,12 @@ import (
|
|||
type controllerTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
client *resourcetest.Client
|
||||
runtime controller.Runtime
|
||||
|
||||
ctl *reconciler
|
||||
ctx context.Context
|
||||
client *resourcetest.Client
|
||||
rt controller.Runtime
|
||||
|
||||
ctl *controller.TestController
|
||||
tenancies []*pbresource.Tenancy
|
||||
|
||||
webWorkload *pbresource.Resource
|
||||
|
||||
|
@ -50,10 +49,6 @@ type controllerTestSuite struct {
|
|||
dbWorkloadID *pbresource.ID
|
||||
dbWorkload *pbcatalog.Workload
|
||||
dbService *pbresource.Resource
|
||||
dbEndpoints *pbresource.Resource
|
||||
dbEndpointsData *pbcatalog.ServiceEndpoints
|
||||
|
||||
tenancies []*pbresource.Tenancy
|
||||
}
|
||||
|
||||
type tenancyKey struct {
|
||||
|
@ -77,28 +72,24 @@ type apiData struct {
|
|||
destinationListenerName string
|
||||
destinationClusterName string
|
||||
serviceData *pbcatalog.Service
|
||||
endpoints *pbresource.Resource
|
||||
endpointsData *pbcatalog.ServiceEndpoints
|
||||
proxyStateTemplate *pbmesh.ProxyStateTemplate
|
||||
}
|
||||
|
||||
func (suite *controllerTestSuite) SetupTest() {
|
||||
trustDomainFetcher := func() (string, error) { return "test.consul", nil }
|
||||
|
||||
suite.tenancies = resourcetest.TestTenancies()
|
||||
resourceClient := svctest.NewResourceServiceBuilder().
|
||||
|
||||
suite.ctx = testutil.TestContext(suite.T())
|
||||
client := svctest.NewResourceServiceBuilder().
|
||||
WithRegisterFns(types.Register, catalog.RegisterTypes, auth.RegisterTypes).
|
||||
WithTenancies(suite.tenancies...).
|
||||
Run(suite.T())
|
||||
|
||||
suite.client = resourcetest.NewClient(resourceClient)
|
||||
suite.runtime = controller.Runtime{Client: resourceClient, Logger: testutil.Logger(suite.T())}
|
||||
suite.ctx = testutil.TestContext(suite.T())
|
||||
|
||||
suite.ctl = &reconciler{
|
||||
cache: cache.New(),
|
||||
getTrustDomain: func() (string, error) {
|
||||
return "test.consul", nil
|
||||
},
|
||||
}
|
||||
suite.ctl = controller.NewTestController(Controller(trustDomainFetcher, "dc1", false), client).
|
||||
WithLogger(testutil.Logger(suite.T()))
|
||||
suite.rt = suite.ctl.Runtime()
|
||||
suite.client = resourcetest.NewClient(suite.rt.Client)
|
||||
|
||||
suite.dbWorkload = &pbcatalog.Workload{
|
||||
Identity: "db-identity",
|
||||
|
@ -133,31 +124,11 @@ func (suite *controllerTestSuite) setupSuiteWithTenancy(tenancy *pbresource.Tena
|
|||
WithTenancy(tenancy).
|
||||
Write(suite.T(), suite.client.ResourceServiceClient).Id
|
||||
|
||||
suite.dbService = resourcetest.Resource(pbcatalog.ServiceType, "db-service").
|
||||
WithData(suite.T(), &pbcatalog.Service{
|
||||
Workloads: &pbcatalog.WorkloadSelector{Names: []string{"db-abc"}},
|
||||
VirtualIps: []string{"1.1.1.1"},
|
||||
Ports: []*pbcatalog.ServicePort{
|
||||
suite.dbService, _, _ = suite.createService(
|
||||
"db-service", tenancy, "db-abc", []*pbcatalog.ServicePort{
|
||||
{TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP},
|
||||
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
}}).
|
||||
WithTenancy(tenancy).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
suite.dbEndpointsData = &pbcatalog.ServiceEndpoints{
|
||||
Endpoints: []*pbcatalog.Endpoint{
|
||||
{
|
||||
TargetRef: suite.dbWorkloadID,
|
||||
Addresses: suite.dbWorkload.Addresses,
|
||||
Ports: suite.dbWorkload.Ports,
|
||||
Identity: "db-identity",
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.dbEndpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "db-service").
|
||||
WithData(suite.T(), suite.dbEndpointsData).
|
||||
WithTenancy(tenancy).
|
||||
Write(suite.T(), suite.client)
|
||||
}, []string{"1.1.1.1"}, []string{"db-identity"}, false)
|
||||
|
||||
suite.api = make(map[tenancyKey]apiData)
|
||||
|
||||
|
@ -193,45 +164,21 @@ func (suite *controllerTestSuite) setupSuiteWithTenancy(tenancy *pbresource.Tena
|
|||
},
|
||||
}
|
||||
|
||||
a.serviceData = &pbcatalog.Service{
|
||||
Workloads: &pbcatalog.WorkloadSelector{Names: []string{"api-abc"}},
|
||||
VirtualIps: []string{"1.1.1.1"},
|
||||
Ports: []*pbcatalog.ServicePort{
|
||||
{TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
},
|
||||
}
|
||||
|
||||
a.workloadID = resourcetest.Resource(pbcatalog.WorkloadType, "api-abc").
|
||||
WithTenancy(t).
|
||||
WithData(suite.T(), a.workload).
|
||||
Write(suite.T(), suite.client.ResourceServiceClient).Id
|
||||
|
||||
a.endpointsData = &pbcatalog.ServiceEndpoints{
|
||||
Endpoints: []*pbcatalog.Endpoint{
|
||||
{
|
||||
TargetRef: a.workloadID,
|
||||
Addresses: a.workload.Addresses,
|
||||
Ports: a.workload.Ports,
|
||||
Identity: "api-identity",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
a.computedTrafficPermissions = resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, a.workload.Identity).
|
||||
WithData(suite.T(), a.computedTrafficPermissionsData).
|
||||
WithTenancy(t).
|
||||
Write(suite.T(), suite.client.ResourceServiceClient)
|
||||
|
||||
a.service = resourcetest.Resource(pbcatalog.ServiceType, "api-service").
|
||||
WithData(suite.T(), a.serviceData).
|
||||
WithTenancy(t).
|
||||
Write(suite.T(), suite.client.ResourceServiceClient)
|
||||
|
||||
a.endpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-service").
|
||||
WithData(suite.T(), a.endpointsData).
|
||||
WithTenancy(t).
|
||||
Write(suite.T(), suite.client.ResourceServiceClient)
|
||||
a.service, a.serviceData, _ = suite.createService(
|
||||
"api-service", t, "api-abc", []*pbcatalog.ServicePort{
|
||||
{TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
}, []string{"1.1.1.1"}, []string{"api-identity"}, false)
|
||||
|
||||
identityRef := &pbresource.Reference{
|
||||
Name: a.workload.Identity,
|
||||
|
@ -260,34 +207,15 @@ func (suite *controllerTestSuite) setupSuiteWithTenancy(tenancy *pbresource.Tena
|
|||
WithTenancy(tenancy).
|
||||
Write(suite.T(), suite.client.ResourceServiceClient)
|
||||
|
||||
resourcetest.Resource(pbcatalog.ServiceType, "web").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), &pbcatalog.Service{
|
||||
Workloads: &pbcatalog.WorkloadSelector{Names: []string{"web-def"}},
|
||||
Ports: []*pbcatalog.ServicePort{
|
||||
suite.createService(
|
||||
"web", tenancy, "web-def", []*pbcatalog.ServicePort{
|
||||
{TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
}}).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
resourcetest.Resource(pbcatalog.ServiceEndpointsType, "web").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), &pbcatalog.ServiceEndpoints{
|
||||
Endpoints: []*pbcatalog.Endpoint{
|
||||
{
|
||||
TargetRef: suite.webWorkload.Id,
|
||||
Addresses: webWorkloadData.Addresses,
|
||||
Ports: webWorkloadData.Ports,
|
||||
Identity: "web-identity",
|
||||
},
|
||||
},
|
||||
}).Write(suite.T(), suite.client)
|
||||
}, nil, []string{"web-identity"}, false)
|
||||
}
|
||||
|
||||
func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_NoServicesInCache() {
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
dataFetcher := fetcher.New(suite.client, suite.ctl.cache)
|
||||
|
||||
workload := resourcetest.Resource(pbcatalog.WorkloadType, "api-workload").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), &pbcatalog.Workload{
|
||||
|
@ -298,7 +226,7 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_NoService
|
|||
Build()
|
||||
|
||||
decWorkload := resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), workload)
|
||||
workloadPorts, err := suite.ctl.workloadPortProtocolsFromService(suite.ctx, dataFetcher, decWorkload, suite.runtime.Logger)
|
||||
workloadPorts, err := workloadPortProtocolsFromService(suite.rt, decWorkload)
|
||||
require.NoError(suite.T(), err)
|
||||
prototest.AssertDeepEqual(suite.T(), pbcatalog.Protocol_PROTOCOL_TCP, workloadPorts["tcp"].GetProtocol())
|
||||
})
|
||||
|
@ -306,15 +234,7 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_NoService
|
|||
|
||||
func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_ServiceNotFound() {
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
c := cache.New()
|
||||
dataFetcher := fetcher.New(suite.client, c)
|
||||
ctrl := &reconciler{
|
||||
cache: c,
|
||||
getTrustDomain: func() (string, error) {
|
||||
return "test.consul", nil
|
||||
},
|
||||
}
|
||||
svc := resourcetest.Resource(pbcatalog.ServiceType, "not-found").
|
||||
resourcetest.Resource(pbcatalog.ServiceType, "not-found").
|
||||
WithData(suite.T(), &pbcatalog.Service{
|
||||
Workloads: &pbcatalog.WorkloadSelector{
|
||||
Names: []string{"api-workload"},
|
||||
|
@ -323,9 +243,6 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_ServiceNo
|
|||
WithTenancy(tenancy).
|
||||
Build()
|
||||
|
||||
decSvc := resourcetest.MustDecode[*pbcatalog.Service](suite.T(), svc)
|
||||
c.TrackService(decSvc)
|
||||
|
||||
workload := resourcetest.Resource(pbcatalog.WorkloadType, "api-workload").
|
||||
WithData(suite.T(), &pbcatalog.Workload{
|
||||
Ports: map[string]*pbcatalog.WorkloadPort{
|
||||
|
@ -337,47 +254,21 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_ServiceNo
|
|||
|
||||
decWorkload := resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), workload)
|
||||
|
||||
workloadPorts, err := ctrl.workloadPortProtocolsFromService(suite.ctx, dataFetcher, decWorkload, suite.runtime.Logger)
|
||||
workloadPorts, err := workloadPortProtocolsFromService(suite.rt, decWorkload)
|
||||
require.NoError(suite.T(), err)
|
||||
prototest.AssertDeepEqual(suite.T(), pbcatalog.Protocol_PROTOCOL_TCP, workloadPorts["tcp"].GetProtocol())
|
||||
// Check that the service is no longer in cache.
|
||||
require.Nil(suite.T(), c.ServicesForWorkload(workload.Id))
|
||||
})
|
||||
}
|
||||
|
||||
func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService() {
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
c := cache.New()
|
||||
dataFetcher := fetcher.New(suite.client, c)
|
||||
ctrl := &reconciler{
|
||||
cache: c,
|
||||
getTrustDomain: func() (string, error) {
|
||||
return "test.consul", nil
|
||||
},
|
||||
}
|
||||
svc1 := resourcetest.Resource(pbcatalog.ServiceType, "api-1").
|
||||
WithData(suite.T(), &pbcatalog.Service{
|
||||
Workloads: &pbcatalog.WorkloadSelector{
|
||||
Names: []string{"api-workload"},
|
||||
},
|
||||
Ports: []*pbcatalog.ServicePort{
|
||||
{
|
||||
TargetPort: "http1",
|
||||
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
||||
},
|
||||
{
|
||||
TargetPort: "conflict",
|
||||
Protocol: pbcatalog.Protocol_PROTOCOL_HTTP,
|
||||
},
|
||||
},
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Write(suite.T(), suite.client)
|
||||
suite.createService(
|
||||
"api-1", tenancy, "api-workload", []*pbcatalog.ServicePort{
|
||||
{TargetPort: "http1", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP},
|
||||
{TargetPort: "conflict", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP},
|
||||
}, nil, nil, false)
|
||||
|
||||
decSvc := resourcetest.MustDecode[*pbcatalog.Service](suite.T(), svc1)
|
||||
c.TrackService(decSvc)
|
||||
|
||||
svc2 := resourcetest.Resource(pbcatalog.ServiceType, "api-2").
|
||||
resourcetest.Resource(pbcatalog.ServiceType, "api-2").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), &pbcatalog.Service{
|
||||
Workloads: &pbcatalog.WorkloadSelector{
|
||||
|
@ -396,9 +287,6 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService() {
|
|||
}).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
decSvc = resourcetest.MustDecode[*pbcatalog.Service](suite.T(), svc2)
|
||||
c.TrackService(decSvc)
|
||||
|
||||
workload := resourcetest.Resource(pbcatalog.WorkloadType, "api-workload").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), &pbcatalog.Workload{
|
||||
|
@ -434,7 +322,7 @@ func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService() {
|
|||
"mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
}
|
||||
|
||||
workloadPorts, err := ctrl.workloadPortProtocolsFromService(suite.ctx, dataFetcher, decWorkload, suite.runtime.Logger)
|
||||
workloadPorts, err := workloadPortProtocolsFromService(suite.rt, decWorkload)
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
prototest.AssertDeepEqual(suite.T(), expWorkloadPorts, workloadPorts)
|
||||
|
@ -445,10 +333,7 @@ func (suite *controllerTestSuite) TestReconcile_NoWorkload() {
|
|||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
// This test ensures that removed workloads are ignored and don't result
|
||||
// in the creation of the proxy state template.
|
||||
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
||||
ID: resourceID(pbmesh.ProxyStateTemplateType, "not-found", tenancy),
|
||||
})
|
||||
require.NoError(suite.T(), err)
|
||||
suite.reconcileOnce(resourceID(pbmesh.ProxyStateTemplateType, "not-found", tenancy))
|
||||
|
||||
suite.client.RequireResourceNotFound(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, "not-found", tenancy))
|
||||
})
|
||||
|
@ -477,11 +362,8 @@ func (suite *controllerTestSuite) TestReconcile_GatewayWorkload() {
|
|||
WithMeta("gateway-kind", "mesh-gateway").
|
||||
Write(suite.T(), suite.client.ResourceServiceClient)
|
||||
|
||||
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
||||
ID: resourceID(pbmesh.ProxyStateTemplateType, "test-gateway-workload", tenancy),
|
||||
})
|
||||
suite.reconcileOnce(resourceID(pbmesh.ProxyStateTemplateType, "test-gateway-workload", tenancy))
|
||||
|
||||
require.NoError(suite.T(), err)
|
||||
suite.client.RequireResourceNotFound(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, "test-non-mesh-api-workload", tenancy))
|
||||
})
|
||||
}
|
||||
|
@ -506,11 +388,8 @@ func (suite *controllerTestSuite) TestReconcile_NonMeshWorkload() {
|
|||
WithTenancy(tenancy).
|
||||
Write(suite.T(), suite.client.ResourceServiceClient)
|
||||
|
||||
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
||||
ID: resourceID(pbmesh.ProxyStateTemplateType, "test-non-mesh-api-workload", tenancy),
|
||||
})
|
||||
suite.reconcileOnce(resourceID(pbmesh.ProxyStateTemplateType, "test-non-mesh-api-workload", tenancy))
|
||||
|
||||
require.NoError(suite.T(), err)
|
||||
suite.client.RequireResourceNotFound(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, "test-non-mesh-api-workload", tenancy))
|
||||
})
|
||||
}
|
||||
|
@ -520,13 +399,9 @@ func (suite *controllerTestSuite) TestReconcile_NoExistingProxyStateTemplate() {
|
|||
|
||||
api := suite.api[toTenancyKey(tenancy)]
|
||||
|
||||
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
||||
ID: resourceID(pbmesh.ProxyStateTemplateType, api.workloadID.Name, tenancy),
|
||||
})
|
||||
require.NoError(suite.T(), err)
|
||||
suite.reconcileOnce(resourceID(pbmesh.ProxyStateTemplateType, api.workloadID.Name, tenancy))
|
||||
|
||||
res := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, api.workloadID.Name, tenancy))
|
||||
require.NoError(suite.T(), err)
|
||||
require.NotNil(suite.T(), res.Data)
|
||||
prototest.AssertDeepEqual(suite.T(), api.workloadID, res.Owner)
|
||||
})
|
||||
|
@ -552,18 +427,14 @@ func (suite *controllerTestSuite) TestReconcile_ExistingProxyStateTemplate_WithU
|
|||
WithData(suite.T(), api.workload).
|
||||
Write(suite.T(), suite.client.ResourceServiceClient).Id
|
||||
|
||||
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
||||
ID: resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name, tenancy),
|
||||
})
|
||||
require.NoError(suite.T(), err)
|
||||
suite.reconcileOnce(resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name, tenancy))
|
||||
|
||||
res := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name, tenancy))
|
||||
require.NoError(suite.T(), err)
|
||||
require.NotNil(suite.T(), res.Data)
|
||||
prototest.AssertDeepEqual(suite.T(), updatedWorkloadID, res.Owner)
|
||||
|
||||
var updatedProxyStateTemplate pbmesh.ProxyStateTemplate
|
||||
err = res.Data.UnmarshalTo(&updatedProxyStateTemplate)
|
||||
err := res.Data.UnmarshalTo(&updatedProxyStateTemplate)
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// Check that our value is updated in the proxy state template.
|
||||
|
@ -594,10 +465,7 @@ func (suite *controllerTestSuite) TestReconcile_ExistingProxyStateTemplate_NoUpd
|
|||
WithMeta("some", "meta").
|
||||
Write(suite.T(), suite.client.ResourceServiceClient).Id
|
||||
|
||||
err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{
|
||||
ID: resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name, tenancy),
|
||||
})
|
||||
require.NoError(suite.T(), err)
|
||||
suite.reconcileOnce(resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name, tenancy))
|
||||
|
||||
updatedProxyState := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, api.workloadID.Name, tenancy))
|
||||
resourcetest.RequireVersionUnchanged(suite.T(), updatedProxyState, originalProxyState.Version)
|
||||
|
@ -605,13 +473,11 @@ func (suite *controllerTestSuite) TestReconcile_ExistingProxyStateTemplate_NoUpd
|
|||
}
|
||||
|
||||
func (suite *controllerTestSuite) TestController() {
|
||||
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
|
||||
|
||||
// Initialize controller dependencies.
|
||||
c := cache.New()
|
||||
trustDomainFetcher := func() (string, error) { return "test.consul", nil }
|
||||
|
||||
mgr.Register(Controller(c, trustDomainFetcher, "dc1", false))
|
||||
// Run the controller manager
|
||||
mgr := controller.NewManager(suite.client, suite.rt.Logger)
|
||||
mgr.Register(Controller(trustDomainFetcher, "dc1", false))
|
||||
mgr.SetRaftLeader(true)
|
||||
go mgr.Run(suite.ctx)
|
||||
|
||||
|
@ -677,7 +543,7 @@ func (suite *controllerTestSuite) TestController() {
|
|||
testutil.RunStep(suite.T(), "add explicit destinations and check that new proxy state is generated", func(t *testing.T) {
|
||||
webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version)
|
||||
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(rt resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(t resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
for _, data := range suite.api {
|
||||
requireExplicitDestinationsFound(t, data.destinationListenerName, data.destinationClusterName, tmpl)
|
||||
}
|
||||
|
@ -690,46 +556,25 @@ func (suite *controllerTestSuite) TestController() {
|
|||
// * api's proxy state template is deleted
|
||||
// * we get a new web proxy resource re-generated
|
||||
// * the status on Upstreams resource is updated with a validation error
|
||||
nonMeshPorts := map[string]*pbcatalog.WorkloadPort{
|
||||
"tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
}
|
||||
|
||||
// Note: the order matters here because in reality service endpoints will only
|
||||
// be reconciled after the workload has been updated, and so we need to write the
|
||||
// workload and service before we write service endpoints.
|
||||
resourcetest.Resource(pbcatalog.WorkloadType, "api-abc").
|
||||
WithTenancy(tenancy).
|
||||
resourcetest.ResourceID(api.workloadID).
|
||||
WithData(suite.T(), &pbcatalog.Workload{
|
||||
Identity: "api-identity",
|
||||
Addresses: api.workload.Addresses,
|
||||
Ports: nonMeshPorts}).
|
||||
Ports: map[string]*pbcatalog.WorkloadPort{
|
||||
"tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
},
|
||||
}).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
api.service = resourcetest.ResourceID(api.service.Id).
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, &pbcatalog.Service{
|
||||
Workloads: &pbcatalog.WorkloadSelector{Names: []string{"api-abc"}},
|
||||
VirtualIps: []string{"1.1.1.1"},
|
||||
Ports: []*pbcatalog.ServicePort{
|
||||
api.service, _, _ = suite.createService(
|
||||
api.service.Id.Name, api.service.Id.Tenancy, "api-abc", []*pbcatalog.ServicePort{
|
||||
{TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
// {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
},
|
||||
}).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-service").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), &pbcatalog.ServiceEndpoints{
|
||||
Endpoints: []*pbcatalog.Endpoint{
|
||||
{
|
||||
TargetRef: api.workloadID,
|
||||
Addresses: api.workload.Addresses,
|
||||
Ports: nonMeshPorts,
|
||||
Identity: "api-identity",
|
||||
},
|
||||
},
|
||||
}).
|
||||
Write(suite.T(), suite.client.ResourceServiceClient)
|
||||
}, []string{"1.1.1.1"}, []string{"api-identity"}, false)
|
||||
|
||||
// Refresh the computed routes in light of api losing a mesh port.
|
||||
routestest.ReconcileComputedRoutes(suite.T(), suite.client, apiComputedRoutesID,
|
||||
|
@ -744,7 +589,7 @@ func (suite *controllerTestSuite) TestController() {
|
|||
// We should get a new web proxy template resource because this destination should be removed.
|
||||
webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version)
|
||||
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(rt resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(t resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
requireExplicitDestinationsNotFound(t, api.destinationListenerName, api.destinationClusterName, tmpl)
|
||||
})
|
||||
})
|
||||
|
@ -752,22 +597,17 @@ func (suite *controllerTestSuite) TestController() {
|
|||
testutil.RunStep(suite.T(), "update ports to be mesh again", func(t *testing.T) {
|
||||
// Update destination's service endpoints back to mesh and check that we get a new web proxy resource re-generated
|
||||
// and that the status on Upstreams resource is updated to be empty.
|
||||
suite.runtime.Logger.Trace("updating ports to mesh")
|
||||
suite.rt.Logger.Trace("updating ports to mesh")
|
||||
|
||||
resourcetest.Resource(pbcatalog.WorkloadType, "api-abc").
|
||||
WithTenancy(tenancy).
|
||||
resourcetest.ResourceID(api.workloadID).
|
||||
WithData(suite.T(), api.workload).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
api.service = resourcetest.Resource(pbcatalog.ServiceType, "api-service").
|
||||
WithData(suite.T(), api.serviceData).
|
||||
WithTenancy(tenancy).
|
||||
Write(suite.T(), suite.client.ResourceServiceClient)
|
||||
|
||||
resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-service").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), api.endpointsData).
|
||||
Write(suite.T(), suite.client.ResourceServiceClient)
|
||||
api.service, api.serviceData, _ = suite.createService(
|
||||
api.service.Id.Name, api.service.Id.Tenancy, "api-abc", []*pbcatalog.ServicePort{
|
||||
{TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
}, []string{"1.1.1.1"}, []string{"api-identity"}, false)
|
||||
|
||||
// Refresh the computed routes in light of api losing a mesh port.
|
||||
routestest.ReconcileComputedRoutes(suite.T(), suite.client, apiComputedRoutesID,
|
||||
|
@ -777,7 +617,7 @@ func (suite *controllerTestSuite) TestController() {
|
|||
// We should also get a new web proxy template resource as this destination should be added again.
|
||||
webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version)
|
||||
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(rt resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(t resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
for _, data := range suite.api {
|
||||
requireExplicitDestinationsFound(t, data.destinationListenerName, data.destinationClusterName, tmpl)
|
||||
}
|
||||
|
@ -786,22 +626,24 @@ func (suite *controllerTestSuite) TestController() {
|
|||
|
||||
testutil.RunStep(suite.T(), "delete the proxy state template and check re-generation", func(t *testing.T) {
|
||||
// Delete the proxy state template resource and check that it gets regenerated.
|
||||
suite.runtime.Logger.Trace("deleting web proxy")
|
||||
suite.rt.Logger.Trace("deleting web proxy")
|
||||
_, err := suite.client.Delete(suite.ctx, &pbresource.DeleteRequest{Id: webProxyStateTemplateID})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version)
|
||||
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(rt resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(t resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
for _, data := range suite.api {
|
||||
requireExplicitDestinationsFound(t, data.destinationListenerName, data.destinationClusterName, tmpl)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
webWrk := resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), suite.webWorkload)
|
||||
|
||||
testutil.RunStep(suite.T(), "add implicit upstream and enable tproxy", func(t *testing.T) {
|
||||
// Delete explicit destinations resource.
|
||||
suite.runtime.Logger.Trace("deleting web destinations")
|
||||
suite.rt.Logger.Trace("deleting web destinations")
|
||||
_, err := suite.client.Delete(suite.ctx, &pbresource.DeleteRequest{Id: webComputedDestinations.Id})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -825,10 +667,32 @@ func (suite *controllerTestSuite) TestController() {
|
|||
},
|
||||
}).Write(suite.T(), suite.client)
|
||||
|
||||
// Write a CID to allow it.
|
||||
cidID := &pbresource.ID{
|
||||
Type: pbmesh.ComputedImplicitDestinationsType,
|
||||
Tenancy: webWrk.Id.Tenancy,
|
||||
Name: webWrk.Data.Identity,
|
||||
}
|
||||
// Write a CID that grants web-identity access to db-identity and api-identity
|
||||
resourcetest.ResourceID(cidID).
|
||||
WithData(suite.T(), &pbmesh.ComputedImplicitDestinations{
|
||||
Destinations: []*pbmesh.ImplicitDestination{
|
||||
{
|
||||
DestinationRef: resource.Reference(api.service.Id, ""),
|
||||
DestinationPorts: []string{"tcp"},
|
||||
},
|
||||
{
|
||||
DestinationRef: resource.Reference(suite.dbService.Id, ""),
|
||||
DestinationPorts: []string{"http"},
|
||||
},
|
||||
},
|
||||
}).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version)
|
||||
apiProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), apiProxyStateTemplateID, apiProxyStateTemplate.Version)
|
||||
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(rt resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(t resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
listenerNameDb := fmt.Sprintf("%s/local/%s/db-service", tenancy.Partition, tenancy.Namespace)
|
||||
clusterNameDb := fmt.Sprintf("db-service.%s.%s", tenancy.Namespace, tenancy.Partition)
|
||||
if tenancy.Partition == "default" {
|
||||
|
@ -844,14 +708,14 @@ func (suite *controllerTestSuite) TestController() {
|
|||
assertTrafficPermissionDefaultPolicy(t, false, apiProxyStateTemplate)
|
||||
assertTrafficPermissionDefaultPolicy(t, false, webProxyStateTemplate)
|
||||
|
||||
suite.runtime.Logger.Trace("deleting computed traffic permissions")
|
||||
suite.rt.Logger.Trace("deleting computed traffic permissions")
|
||||
_, err := suite.client.Delete(suite.ctx, &pbresource.DeleteRequest{Id: api.computedTrafficPermissions.Id})
|
||||
require.NoError(t, err)
|
||||
suite.client.WaitForDeletion(t, api.computedTrafficPermissions.Id)
|
||||
|
||||
apiProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), apiProxyStateTemplateID, apiProxyStateTemplate.Version)
|
||||
|
||||
suite.runtime.Logger.Trace("creating computed traffic permissions")
|
||||
suite.rt.Logger.Trace("creating computed traffic permissions")
|
||||
resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, api.workload.Identity).
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, api.computedTrafficPermissionsData).
|
||||
|
@ -908,7 +772,7 @@ func (suite *controllerTestSuite) TestController() {
|
|||
|
||||
webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version)
|
||||
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(rt resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
suite.waitForProxyStateTemplateState(t, webProxyStateTemplateID, func(t resourcetest.T, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
listenerNameDb := fmt.Sprintf("%s/local/%s/db-service", tenancy.Partition, tenancy.Namespace)
|
||||
clusterNameDb := fmt.Sprintf("db-service.%s.%s", tenancy.Namespace, tenancy.Partition)
|
||||
if tenancy.Partition == "default" {
|
||||
|
@ -923,14 +787,11 @@ func (suite *controllerTestSuite) TestController() {
|
|||
|
||||
func (suite *controllerTestSuite) TestControllerDefaultAllow() {
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
// Run the controller manager
|
||||
mgr := controller.NewManager(suite.client, suite.runtime.Logger)
|
||||
|
||||
// Initialize controller dependencies.
|
||||
c := cache.New()
|
||||
trustDomainFetcher := func() (string, error) { return "test.consul", nil }
|
||||
|
||||
mgr.Register(Controller(c, trustDomainFetcher, "dc1", true))
|
||||
// Run the controller manager
|
||||
mgr := controller.NewManager(suite.client, suite.rt.Logger)
|
||||
mgr.Register(Controller(trustDomainFetcher, "dc1", true))
|
||||
mgr.SetRaftLeader(true)
|
||||
go mgr.Run(suite.ctx)
|
||||
|
||||
|
@ -955,11 +816,13 @@ func TestMeshController(t *testing.T) {
|
|||
suite.Run(t, new(controllerTestSuite))
|
||||
}
|
||||
|
||||
func requireExplicitDestinationsFound(t *testing.T, listenerName, clusterName string, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
func requireExplicitDestinationsFound(t resourcetest.T, listenerName, clusterName string, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
t.Helper()
|
||||
requireExplicitDestinations(t, listenerName, clusterName, tmpl, true)
|
||||
}
|
||||
|
||||
func requireExplicitDestinationsNotFound(t *testing.T, listenerName, clusterName string, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
func requireExplicitDestinationsNotFound(t resourcetest.T, listenerName, clusterName string, tmpl *pbmesh.ProxyStateTemplate) {
|
||||
t.Helper()
|
||||
requireExplicitDestinations(t, listenerName, clusterName, tmpl, false)
|
||||
}
|
||||
|
||||
|
@ -967,15 +830,20 @@ func requireExplicitDestinations(t resourcetest.T, listenerName string, clusterN
|
|||
t.Helper()
|
||||
|
||||
// Check outbound listener.
|
||||
var foundListener bool
|
||||
var (
|
||||
foundListener bool
|
||||
allListenerNames []string
|
||||
)
|
||||
for _, l := range tmpl.ProxyState.Listeners {
|
||||
allListenerNames = append(allListenerNames, l.Name)
|
||||
if l.Name == listenerName && l.Direction == pbproxystate.Direction_DIRECTION_OUTBOUND {
|
||||
foundListener = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.Equal(t, found, foundListener)
|
||||
require.Equal(t, found, foundListener,
|
||||
"listener: needle=%q shouldFind=%v haystack=%v",
|
||||
listenerName, found, allListenerNames)
|
||||
|
||||
requireClustersAndEndpoints(t, clusterName, tmpl, found)
|
||||
}
|
||||
|
@ -1026,34 +894,42 @@ func requireImplicitDestinationsFound(t resourcetest.T, listenerName string, clu
|
|||
func requireClustersAndEndpoints(t resourcetest.T, clusterName string, tmpl *pbmesh.ProxyStateTemplate, found bool) {
|
||||
t.Helper()
|
||||
|
||||
var foundCluster bool
|
||||
var (
|
||||
foundCluster bool
|
||||
allClusterNames []string
|
||||
)
|
||||
for c := range tmpl.ProxyState.Clusters {
|
||||
allClusterNames = append(allClusterNames, c)
|
||||
if strings.Contains(c, clusterName) {
|
||||
foundCluster = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.Equal(t, found, foundCluster)
|
||||
require.Equal(t, found, foundCluster,
|
||||
"cluster: needle=%q shouldFind=%v haystack=%v",
|
||||
clusterName, found, allClusterNames)
|
||||
|
||||
var foundEndpoints bool
|
||||
var (
|
||||
foundEndpoints bool
|
||||
allEndpointsNames []string
|
||||
)
|
||||
for c := range tmpl.RequiredEndpoints {
|
||||
allEndpointsNames = append(allEndpointsNames, c)
|
||||
if strings.Contains(c, clusterName) {
|
||||
foundEndpoints = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
require.Equal(t, found, foundEndpoints)
|
||||
require.Equal(t, found, foundEndpoints,
|
||||
"endpoints: needle=%q shouldFind=%v haystack=%v",
|
||||
clusterName, found, allEndpointsNames)
|
||||
}
|
||||
|
||||
func (suite *controllerTestSuite) waitForProxyStateTemplateState(t *testing.T, id *pbresource.ID, verify func(resourcetest.T, *pbmesh.ProxyStateTemplate)) {
|
||||
suite.client.WaitForResourceState(t, id, func(rt resourcetest.T, res *pbresource.Resource) {
|
||||
var tmpl pbmesh.ProxyStateTemplate
|
||||
err := res.Data.UnmarshalTo(&tmpl)
|
||||
require.NoError(rt, err)
|
||||
|
||||
verify(rt, &tmpl)
|
||||
suite.client.WaitForResourceState(t, id, func(t resourcetest.T, res *pbresource.Resource) {
|
||||
dec := resourcetest.MustDecode[*pbmesh.ProxyStateTemplate](t, res)
|
||||
verify(t, dec.Data)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1085,17 +961,14 @@ func (suite *controllerTestSuite) appendTenancyInfo(tenancy *pbresource.Tenancy)
|
|||
}
|
||||
|
||||
func (suite *controllerTestSuite) cleanupResources() {
|
||||
|
||||
for _, api := range suite.api {
|
||||
suite.client.MustDelete(suite.T(), api.workloadID)
|
||||
suite.client.MustDelete(suite.T(), api.computedTrafficPermissions.Id)
|
||||
suite.client.MustDelete(suite.T(), api.service.Id)
|
||||
suite.client.MustDelete(suite.T(), api.endpoints.Id)
|
||||
}
|
||||
suite.client.MustDelete(suite.T(), suite.webWorkload.Id)
|
||||
suite.client.MustDelete(suite.T(), suite.dbWorkloadID)
|
||||
suite.client.MustDelete(suite.T(), suite.dbService.Id)
|
||||
suite.client.MustDelete(suite.T(), suite.dbEndpoints.Id)
|
||||
}
|
||||
|
||||
func (suite *controllerTestSuite) runTestCaseWithTenancies(t func(*pbresource.Tenancy)) {
|
||||
|
@ -1109,3 +982,23 @@ func (suite *controllerTestSuite) runTestCaseWithTenancies(t func(*pbresource.Te
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *controllerTestSuite) reconcileOnce(id *pbresource.ID) {
|
||||
err := suite.ctl.Reconcile(suite.ctx, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
suite.T().Cleanup(func() {
|
||||
suite.client.CleanupDelete(suite.T(), id)
|
||||
})
|
||||
}
|
||||
|
||||
func (suite *controllerTestSuite) createService(
|
||||
name string,
|
||||
tenancy *pbresource.Tenancy,
|
||||
exactSelector string,
|
||||
ports []*pbcatalog.ServicePort,
|
||||
vips []string,
|
||||
workloadIdentities []string,
|
||||
deferStatusUpdate bool,
|
||||
) (*pbresource.Resource, *pbcatalog.Service, func() *pbresource.Resource) {
|
||||
return createService(suite.T(), suite.client, name, tenancy, exactSelector, ports, vips, workloadIdentities, deferStatusUpdate)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package sidecarproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/hashicorp/consul/internal/catalog"
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/controller/cache"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/meshgateways"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
intermediateTypes "github.com/hashicorp/consul/internal/mesh/internal/types/intermediate"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
)
|
||||
|
||||
func FetchUnifiedDestinationsData(
|
||||
ctx context.Context,
|
||||
rt controller.Runtime,
|
||||
workload *types.DecodedWorkload,
|
||||
mgwMode pbmesh.MeshGatewayMode,
|
||||
transparentProxyEnabled bool,
|
||||
) ([]*intermediateTypes.Destination, error) {
|
||||
// Get all destinationsData.
|
||||
destinationsData, err := fetchComputedExplicitDestinationsData(rt, workload, mgwMode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if transparentProxyEnabled {
|
||||
rt.Logger.Trace("transparent proxy is enabled; fetching implicit destinations")
|
||||
destinationsData, err = fetchComputedImplicitDestinationsData(rt, workload, mgwMode, destinationsData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return destinationsData, nil
|
||||
}
|
||||
|
||||
func fetchComputedExplicitDestinationsData(
|
||||
rt controller.Runtime,
|
||||
workload *types.DecodedWorkload,
|
||||
mgwMode pbmesh.MeshGatewayMode,
|
||||
) ([]*intermediateTypes.Destination, error) {
|
||||
cedID := resource.ReplaceType(pbmesh.ComputedExplicitDestinationsType, workload.Id)
|
||||
|
||||
var destinations []*intermediateTypes.Destination
|
||||
|
||||
// Fetch computed explicit destinations first.
|
||||
cd, err := cache.GetDecoded[*pbmesh.ComputedExplicitDestinations](rt.Cache, pbmesh.ComputedExplicitDestinationsType, "id", cedID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if cd == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, dest := range cd.GetData().GetDestinations() {
|
||||
serviceID := resource.IDFromReference(dest.DestinationRef)
|
||||
|
||||
outDests, err := fetchSingleDestinationData(rt, workload.Id, mgwMode, serviceID, nil, dest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if len(outDests) == 0 {
|
||||
continue // skip
|
||||
}
|
||||
|
||||
// For explicit dests, we are guaranteed only one result.
|
||||
destinations = append(destinations, outDests[0])
|
||||
}
|
||||
|
||||
return destinations, nil
|
||||
}
|
||||
|
||||
type PortReferenceKey struct {
|
||||
resource.ReferenceKey
|
||||
Port string
|
||||
}
|
||||
|
||||
// fetchImplicitDestinationsData fetches all implicit destinations and adds them to existing destinations.
|
||||
// If the implicit destination is already in addToDestinations, it will be skipped.
|
||||
//
|
||||
// Rename to include computed term
|
||||
func fetchComputedImplicitDestinationsData(
|
||||
rt controller.Runtime,
|
||||
workload *types.DecodedWorkload,
|
||||
mgwMode pbmesh.MeshGatewayMode,
|
||||
addToDestinations []*intermediateTypes.Destination,
|
||||
) ([]*intermediateTypes.Destination, error) {
|
||||
cidID := &pbresource.ID{
|
||||
Type: pbmesh.ComputedImplicitDestinationsType,
|
||||
Name: workload.Data.Identity,
|
||||
Tenancy: workload.Id.Tenancy,
|
||||
}
|
||||
|
||||
// First, convert existing destinations to a map so we can de-dup.
|
||||
//
|
||||
// This is keyed by the serviceID+port of the upstream, which is effectively
|
||||
// the same as the id of the computed routes for the service.
|
||||
destsSeen := make(map[PortReferenceKey]struct{})
|
||||
for _, d := range addToDestinations {
|
||||
prk := PortReferenceKey{
|
||||
ReferenceKey: resource.NewReferenceKey(d.Service.Resource.Id),
|
||||
Port: d.ComputedPortRoutes.ParentRef.Port,
|
||||
}
|
||||
destsSeen[prk] = struct{}{}
|
||||
}
|
||||
|
||||
cid, err := cache.GetDecoded[*pbmesh.ComputedImplicitDestinations](
|
||||
rt.Cache,
|
||||
pbmesh.ComputedImplicitDestinationsType,
|
||||
"id",
|
||||
cidID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if cid == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, dest := range cid.Data.GetDestinations() {
|
||||
serviceID := resource.IDFromReference(dest.DestinationRef)
|
||||
|
||||
outDests, err := fetchSingleDestinationData(rt, workload.Id, mgwMode, serviceID, dest.DestinationPorts, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if len(outDests) == 0 {
|
||||
continue // skip
|
||||
}
|
||||
|
||||
for _, od := range outDests {
|
||||
// If it's already in destinations, ignore it.
|
||||
portName := od.ComputedPortRoutes.ParentRef.Port
|
||||
prk := PortReferenceKey{
|
||||
ReferenceKey: resource.NewReferenceKey(od.Service.Id),
|
||||
Port: portName,
|
||||
}
|
||||
if _, ok := destsSeen[prk]; ok {
|
||||
continue
|
||||
}
|
||||
addToDestinations = append(addToDestinations, od)
|
||||
}
|
||||
}
|
||||
return addToDestinations, err
|
||||
}
|
||||
|
||||
func fetchSingleDestinationData(
|
||||
rt controller.Runtime,
|
||||
workloadID *pbresource.ID,
|
||||
mgwMode pbmesh.MeshGatewayMode,
|
||||
serviceID *pbresource.ID,
|
||||
destPorts []string,
|
||||
explicitDest *pbmesh.Destination,
|
||||
) ([]*intermediateTypes.Destination, error) {
|
||||
assertResourceType(pbcatalog.ServiceType, serviceID.Type)
|
||||
|
||||
if explicitDest != nil {
|
||||
// Force this input regardless of what was asked.
|
||||
destPorts = []string{explicitDest.DestinationPort}
|
||||
}
|
||||
|
||||
proxyTenancy := workloadID.GetTenancy()
|
||||
|
||||
// Fetch Service
|
||||
svc, err := cache.GetDecoded[*pbcatalog.Service](rt.Cache, pbcatalog.ServiceType, "id", serviceID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if svc == nil {
|
||||
// If the Service resource is not found, skip this destination.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Check if this service is mesh-enabled. If not, update the status.
|
||||
if !svc.GetData().IsMeshEnabled() {
|
||||
// This error should not cause the execution to stop, as we want to make sure that this non-mesh destination
|
||||
// service gets removed from the proxy state.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// If this proxy is a part of this service, ignore it.
|
||||
if explicitDest == nil && isPartOfService(workloadID, svc) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
ports := make(map[string]struct{})
|
||||
for _, p := range destPorts {
|
||||
ports[p] = struct{}{}
|
||||
}
|
||||
|
||||
// Remove any desired ports that do not exist on the service.
|
||||
for port := range ports {
|
||||
if svc.GetData().FindPortByID(port) == nil {
|
||||
delete(ports, port)
|
||||
continue
|
||||
}
|
||||
|
||||
// No destination port should point to a port with "mesh" protocol,
|
||||
// so check if destination port has the mesh protocol and skip it if it does.
|
||||
if svc.GetData().FindPortByID(port).GetProtocol() == pbcatalog.Protocol_PROTOCOL_MESH {
|
||||
delete(ports, port)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if len(ports) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Fetch ComputedRoutes.
|
||||
crID := resource.ReplaceType(pbmesh.ComputedRoutesType, serviceID)
|
||||
cr, err := cache.GetDecoded[*pbmesh.ComputedRoutes](rt.Cache, pbmesh.ComputedRoutesType, "id", crID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if cr == nil {
|
||||
// This is required, so wait until it exists.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var dests []*intermediateTypes.Destination
|
||||
for port := range ports {
|
||||
portConfig, ok := cr.Data.PortedConfigs[port]
|
||||
if !ok {
|
||||
// This is required, so wait until it exists.
|
||||
delete(ports, port)
|
||||
continue
|
||||
}
|
||||
|
||||
d := &intermediateTypes.Destination{
|
||||
Service: svc,
|
||||
// Copy this so we can mutate the targets.
|
||||
ComputedPortRoutes: proto.Clone(portConfig).(*pbmesh.ComputedPortRoutes),
|
||||
}
|
||||
|
||||
if explicitDest != nil {
|
||||
// As Destinations resource contains a list of destinations,
|
||||
// we need to find the one that references our service and port.
|
||||
d.Explicit = explicitDest
|
||||
} else {
|
||||
// todo (ishustava): this should eventually grab virtual IPs resource.
|
||||
d.VirtualIPs = svc.Data.VirtualIps
|
||||
}
|
||||
|
||||
// NOTE: we collect both DIRECT and INDIRECT target information here.
|
||||
for _, routeTarget := range d.ComputedPortRoutes.Targets {
|
||||
targetServiceID := resource.IDFromReference(routeTarget.BackendRef.Ref)
|
||||
|
||||
// Fetch Service
|
||||
targetSvc, err := rt.Cache.Get(pbcatalog.ServiceType, "id", targetServiceID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if targetSvc == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Gather all identities.
|
||||
ids := catalog.GetBoundIdentities(targetSvc)
|
||||
routeTarget.IdentityRefs = make([]*pbresource.Reference, len(ids))
|
||||
for i, id := range ids {
|
||||
routeTarget.IdentityRefs[i] = &pbresource.Reference{
|
||||
Name: id,
|
||||
Tenancy: svc.Id.Tenancy,
|
||||
}
|
||||
}
|
||||
|
||||
routeTarget.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, targetServiceID),
|
||||
MeshPort: routeTarget.MeshPort,
|
||||
RoutePort: routeTarget.BackendRef.Port,
|
||||
}
|
||||
|
||||
// If the target service is in a different partition and the mesh gateway mode is
|
||||
// "local" or "remote", use the ServiceEndpoints for the corresponding MeshGateway
|
||||
// instead of the ServiceEndpoints for the target service. The IdentityRefs on the
|
||||
// target will remain the same for TCP targets.
|
||||
//
|
||||
// TODO(nathancoleman) Consider cross-datacenter case as well
|
||||
if routeTarget.BackendRef.Ref.Tenancy.Partition != proxyTenancy.Partition {
|
||||
switch mgwMode {
|
||||
case pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_LOCAL:
|
||||
// Use ServiceEndpoints for the MeshGateway in the source service's partition
|
||||
routeTarget.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: &pbresource.ID{
|
||||
Type: pbcatalog.ServiceEndpointsType,
|
||||
Name: meshgateways.GatewayName,
|
||||
Tenancy: proxyTenancy,
|
||||
},
|
||||
MeshPort: meshgateways.LANPortName,
|
||||
RoutePort: meshgateways.LANPortName,
|
||||
}
|
||||
case pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_REMOTE:
|
||||
// Use ServiceEndpoints for the MeshGateway in the target service's partition
|
||||
routeTarget.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: &pbresource.ID{
|
||||
Type: pbcatalog.ServiceEndpointsType,
|
||||
Name: meshgateways.GatewayName,
|
||||
Tenancy: targetServiceID.Tenancy,
|
||||
},
|
||||
MeshPort: meshgateways.WANPortName,
|
||||
RoutePort: meshgateways.WANPortName,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dests = append(dests, d)
|
||||
}
|
||||
|
||||
return dests, nil
|
||||
}
|
||||
|
||||
func isPartOfService(workloadID *pbresource.ID, svc *types.DecodedService) bool {
|
||||
if !resource.EqualTenancy(workloadID.GetTenancy(), svc.Resource.Id.GetTenancy()) {
|
||||
return false
|
||||
}
|
||||
sel := svc.Data.Workloads
|
||||
for _, exact := range sel.GetNames() {
|
||||
if workloadID.GetName() == exact {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, prefix := range sel.GetPrefixes() {
|
||||
if strings.HasPrefix(workloadID.GetName(), prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -1,26 +1,26 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package fetcher
|
||||
package sidecarproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing"
|
||||
"github.com/hashicorp/consul/internal/auth"
|
||||
"github.com/hashicorp/consul/internal/catalog"
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/routestest"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types/intermediate"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate"
|
||||
|
@ -33,103 +33,51 @@ type dataFetcherSuite struct {
|
|||
suite.Suite
|
||||
|
||||
ctx context.Context
|
||||
client pbresource.ResourceServiceClient
|
||||
resourceClient *resourcetest.Client
|
||||
client *resourcetest.Client
|
||||
rt controller.Runtime
|
||||
|
||||
ctl *controller.TestController
|
||||
tenancies []*pbresource.Tenancy
|
||||
|
||||
api1Service *pbresource.Resource
|
||||
api1ServiceData *pbcatalog.Service
|
||||
api2Service *pbresource.Resource
|
||||
api2ServiceData *pbcatalog.Service
|
||||
api1ServiceEndpoints *pbresource.Resource
|
||||
api1ServiceEndpointsData *pbcatalog.ServiceEndpoints
|
||||
api2ServiceEndpoints *pbresource.Resource
|
||||
api2ServiceEndpointsData *pbcatalog.ServiceEndpoints
|
||||
proxyCfg *pbmesh.ComputedProxyConfiguration
|
||||
webComputedDestinationsData *pbmesh.ComputedExplicitDestinations
|
||||
webProxy *pbresource.Resource
|
||||
webWorkload *pbresource.Resource
|
||||
tenancies []*pbresource.Tenancy
|
||||
}
|
||||
|
||||
func (suite *dataFetcherSuite) SetupTest() {
|
||||
suite.ctx = testutil.TestContext(suite.T())
|
||||
trustDomainFetcher := func() (string, error) { return "test.consul", nil }
|
||||
|
||||
suite.tenancies = resourcetest.TestTenancies()
|
||||
suite.client = svctest.NewResourceServiceBuilder().
|
||||
WithRegisterFns(types.Register, catalog.RegisterTypes).
|
||||
|
||||
suite.ctx = testutil.TestContext(suite.T())
|
||||
client := svctest.NewResourceServiceBuilder().
|
||||
WithRegisterFns(types.Register, catalog.RegisterTypes, auth.RegisterTypes).
|
||||
WithTenancies(suite.tenancies...).
|
||||
Run(suite.T())
|
||||
suite.resourceClient = resourcetest.NewClient(suite.client)
|
||||
suite.rt = controller.Runtime{
|
||||
Client: suite.client,
|
||||
Logger: testutil.Logger(suite.T()),
|
||||
}
|
||||
|
||||
suite.ctl = controller.NewTestController(Controller(trustDomainFetcher, "dc1", false), client).
|
||||
WithLogger(testutil.Logger(suite.T()))
|
||||
suite.rt = suite.ctl.Runtime()
|
||||
suite.client = resourcetest.NewClient(suite.rt.Client)
|
||||
}
|
||||
|
||||
func (suite *dataFetcherSuite) setupWithTenancy(tenancy *pbresource.Tenancy) {
|
||||
suite.api1ServiceData = &pbcatalog.Service{
|
||||
Ports: []*pbcatalog.ServicePort{
|
||||
suite.api1Service, suite.api1ServiceData, _ = suite.createService(
|
||||
"api-1", tenancy, "api1", []*pbcatalog.ServicePort{
|
||||
{TargetPort: "tcp", VirtualPort: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
{TargetPort: "mesh", VirtualPort: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
},
|
||||
}
|
||||
suite.api1Service = resourcetest.Resource(pbcatalog.ServiceType, "api-1").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), suite.api1ServiceData).
|
||||
Write(suite.T(), suite.client)
|
||||
}, nil, []string{"api-1-identity"}, false)
|
||||
|
||||
suite.api1ServiceEndpointsData = &pbcatalog.ServiceEndpoints{
|
||||
Endpoints: []*pbcatalog.Endpoint{
|
||||
{
|
||||
Addresses: []*pbcatalog.WorkloadAddress{{Host: "10.0.0.1"}},
|
||||
Ports: map[string]*pbcatalog.WorkloadPort{
|
||||
"tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
"mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
},
|
||||
Identity: "api-1-identity",
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.api1ServiceEndpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-1").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), suite.api1ServiceEndpointsData).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
suite.api2ServiceData = &pbcatalog.Service{
|
||||
Ports: []*pbcatalog.ServicePort{
|
||||
suite.api2Service, suite.api2ServiceData, _ = suite.createService(
|
||||
"api-2", tenancy, "api2", []*pbcatalog.ServicePort{
|
||||
{TargetPort: "tcp1", VirtualPort: 9080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
{TargetPort: "tcp2", VirtualPort: 9081, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
{TargetPort: "mesh", VirtualPort: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
},
|
||||
}
|
||||
suite.api2Service = resourcetest.Resource(pbcatalog.ServiceType, "api-2").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), suite.api2ServiceData).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
suite.api2ServiceEndpointsData = &pbcatalog.ServiceEndpoints{
|
||||
Endpoints: []*pbcatalog.Endpoint{
|
||||
{
|
||||
Addresses: []*pbcatalog.WorkloadAddress{{Host: "10.0.0.2"}},
|
||||
Ports: map[string]*pbcatalog.WorkloadPort{
|
||||
"tcp1": {Port: 9080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
"tcp2": {Port: 9081, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
"mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
},
|
||||
Identity: "api-2-identity",
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.api2ServiceEndpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-2").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), suite.api2ServiceEndpointsData).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
suite.proxyCfg = &pbmesh.ComputedProxyConfiguration{
|
||||
DynamicConfig: &pbmesh.DynamicConfig{
|
||||
MeshGatewayMode: pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_NONE,
|
||||
},
|
||||
}
|
||||
}, nil, []string{"api-2-identity"}, false)
|
||||
|
||||
suite.webComputedDestinationsData = &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
|
@ -158,112 +106,25 @@ func (suite *dataFetcherSuite) setupWithTenancy(tenancy *pbresource.Tenancy) {
|
|||
WithData(suite.T(), &pbcatalog.Workload{
|
||||
Addresses: []*pbcatalog.WorkloadAddress{{Host: "10.0.0.2"}},
|
||||
Ports: map[string]*pbcatalog.WorkloadPort{"tcp": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}},
|
||||
Identity: "web-id-abc",
|
||||
}).
|
||||
Write(suite.T(), suite.client)
|
||||
}
|
||||
|
||||
func (suite *dataFetcherSuite) TestFetcher_FetchWorkload_WorkloadNotFound() {
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
identityID := resourcetest.Resource(pbauth.WorkloadIdentityType, "workload-identity-abc").
|
||||
WithTenancy(tenancy).ID()
|
||||
|
||||
// Create cache and pre-populate it.
|
||||
c := cache.New()
|
||||
|
||||
f := Fetcher{
|
||||
cache: c,
|
||||
client: suite.client,
|
||||
}
|
||||
|
||||
workloadID := resourcetest.Resource(pbcatalog.WorkloadType, "not-found").WithTenancy(tenancy).ID()
|
||||
|
||||
// Track workload with its identity.
|
||||
workload := resourcetest.Resource(pbcatalog.WorkloadType, workloadID.GetName()).
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), &pbcatalog.Workload{
|
||||
Identity: identityID.Name,
|
||||
}).Build()
|
||||
|
||||
c.TrackWorkload(resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), workload))
|
||||
|
||||
// Now fetch the workload so that we can check that it's been removed from cache.
|
||||
_, err := f.FetchWorkload(context.Background(), workloadID)
|
||||
require.NoError(suite.T(), err)
|
||||
require.Nil(suite.T(), c.WorkloadsByWorkloadIdentity(identityID))
|
||||
})
|
||||
}
|
||||
|
||||
func (suite *dataFetcherSuite) TestFetcher_FetchWorkload_WorkloadFound() {
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
identityID := resourcetest.Resource(pbauth.WorkloadIdentityType, "workload-identity-abc").
|
||||
WithTenancy(tenancy).ID()
|
||||
|
||||
// Create cache and pre-populate it.
|
||||
c := cache.New()
|
||||
|
||||
f := Fetcher{
|
||||
cache: c,
|
||||
client: suite.client,
|
||||
}
|
||||
|
||||
workload := resourcetest.Resource(pbcatalog.WorkloadType, "service-workload-abc").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), &pbcatalog.Workload{
|
||||
Identity: identityID.Name,
|
||||
Ports: map[string]*pbcatalog.WorkloadPort{
|
||||
"foo": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP},
|
||||
},
|
||||
Addresses: []*pbcatalog.WorkloadAddress{
|
||||
{
|
||||
Host: "10.0.0.1",
|
||||
Ports: []string{"foo"},
|
||||
},
|
||||
},
|
||||
}).Write(suite.T(), suite.client)
|
||||
|
||||
// This call should track the workload's identity
|
||||
_, err := f.FetchWorkload(context.Background(), workload.Id)
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// Check that the workload is tracked
|
||||
workload.Id.Uid = ""
|
||||
prototest.AssertElementsMatch(suite.T(), []*pbresource.ID{workload.Id}, c.WorkloadsByWorkloadIdentity(identityID))
|
||||
})
|
||||
}
|
||||
|
||||
func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
||||
const mgwMode = pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_NONE
|
||||
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
c := cache.New()
|
||||
|
||||
api1ServiceRef := resource.Reference(suite.api1Service.Id, "")
|
||||
|
||||
f := Fetcher{
|
||||
cache: c,
|
||||
client: suite.client,
|
||||
}
|
||||
webWrk := resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), suite.webWorkload)
|
||||
|
||||
testutil.RunStep(suite.T(), "computed destinations not found", func(t *testing.T) {
|
||||
// First add computed destination to cache so we can check if it's untracked later.
|
||||
compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name).
|
||||
WithData(t, &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
{
|
||||
DestinationRef: api1ServiceRef,
|
||||
DestinationPort: "tcp1",
|
||||
},
|
||||
},
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Build()
|
||||
c.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDest))
|
||||
|
||||
// We will try to fetch explicit destinations for a proxy that doesn't have one.
|
||||
destinations, err := f.FetchComputedExplicitDestinationsData(suite.ctx, suite.webProxy.Id, suite.proxyCfg)
|
||||
destinations, err := fetchComputedExplicitDestinationsData(suite.rt, webWrk, mgwMode)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, destinations)
|
||||
|
||||
// Check that cache no longer has this destination.
|
||||
require.Nil(t, c.ComputedDestinationsByService(resource.IDFromReference(api1ServiceRef)))
|
||||
})
|
||||
|
||||
testutil.RunStep(suite.T(), "invalid destinations: service not found", func(t *testing.T) {
|
||||
|
@ -271,7 +132,7 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
WithTenancy(tenancy).
|
||||
ReferenceNoSection()
|
||||
|
||||
compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name).
|
||||
resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name).
|
||||
WithData(t, &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
{
|
||||
|
@ -283,12 +144,9 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
WithTenancy(tenancy).
|
||||
Write(t, suite.client)
|
||||
|
||||
destinations, err := f.FetchComputedExplicitDestinationsData(suite.ctx, suite.webProxy.Id, suite.proxyCfg)
|
||||
destinations, err := fetchComputedExplicitDestinationsData(suite.rt, webWrk, mgwMode)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, destinations)
|
||||
cachedCompDestIDs := c.ComputedDestinationsByService(resource.IDFromReference(notFoundServiceRef))
|
||||
compDest.Id.Uid = ""
|
||||
prototest.AssertElementsMatch(t, []*pbresource.ID{compDest.Id}, cachedCompDestIDs)
|
||||
})
|
||||
|
||||
testutil.RunStep(suite.T(), "invalid destinations: service not on mesh", func(t *testing.T) {
|
||||
|
@ -301,7 +159,7 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
WithTenancy(tenancy).
|
||||
WithData(t, apiNonMeshServiceData).
|
||||
Write(t, suite.client)
|
||||
compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name).
|
||||
resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name).
|
||||
WithData(t, &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
{
|
||||
|
@ -313,25 +171,18 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
WithTenancy(tenancy).
|
||||
Write(t, suite.client)
|
||||
|
||||
destinations, err := f.FetchComputedExplicitDestinationsData(suite.ctx, suite.webProxy.Id, suite.proxyCfg)
|
||||
destinations, err := fetchComputedExplicitDestinationsData(suite.rt, webWrk, mgwMode)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, destinations)
|
||||
cachedCompDestIDs := c.ComputedDestinationsByService(resource.IDFromReference(api1ServiceRef))
|
||||
compDest.Id.Uid = ""
|
||||
prototest.AssertElementsMatch(t, []*pbresource.ID{compDest.Id}, cachedCompDestIDs)
|
||||
})
|
||||
|
||||
testutil.RunStep(suite.T(), "invalid destinations: destination port not found", func(t *testing.T) {
|
||||
resourcetest.ResourceID(suite.api1Service.Id).
|
||||
WithData(t, &pbcatalog.Service{
|
||||
Ports: []*pbcatalog.ServicePort{
|
||||
suite.api1Service, _, _ = suite.createService(
|
||||
"api-1", tenancy, "api1", []*pbcatalog.ServicePort{
|
||||
{TargetPort: "some-other-port", Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
{TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
},
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Write(t, suite.client)
|
||||
compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name).
|
||||
}, nil, []string{"api-1-identity"}, false)
|
||||
resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name).
|
||||
WithData(t, &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
{
|
||||
|
@ -343,12 +194,9 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
WithTenancy(tenancy).
|
||||
Write(t, suite.client)
|
||||
|
||||
destinations, err := f.FetchComputedExplicitDestinationsData(suite.ctx, suite.webProxy.Id, suite.proxyCfg)
|
||||
destinations, err := fetchComputedExplicitDestinationsData(suite.rt, webWrk, mgwMode)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, destinations)
|
||||
cachedCompDestIDs := c.ComputedDestinationsByService(resource.IDFromReference(api1ServiceRef))
|
||||
compDest.Id.Uid = ""
|
||||
prototest.AssertElementsMatch(t, []*pbresource.ID{compDest.Id}, cachedCompDestIDs)
|
||||
})
|
||||
|
||||
suite.api1Service = resourcetest.ResourceID(suite.api1Service.Id).
|
||||
|
@ -363,7 +211,7 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
|
||||
testutil.RunStep(suite.T(), "invalid destinations: destination is pointing to a mesh port", func(t *testing.T) {
|
||||
// Create a computed destinations resource pointing to the mesh port.
|
||||
compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name).
|
||||
resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name).
|
||||
WithData(t, &pbmesh.ComputedExplicitDestinations{
|
||||
Destinations: []*pbmesh.Destination{
|
||||
{
|
||||
|
@ -375,16 +223,12 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
WithTenancy(tenancy).
|
||||
Write(t, suite.client)
|
||||
|
||||
destinations, err := f.FetchComputedExplicitDestinationsData(suite.ctx, suite.webProxy.Id, suite.proxyCfg)
|
||||
destinations, err := fetchComputedExplicitDestinationsData(suite.rt, webWrk, mgwMode)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, destinations)
|
||||
|
||||
cachedCompDestIDs := c.ComputedDestinationsByService(resource.IDFromReference(api1ServiceRef))
|
||||
compDest.Id.Uid = ""
|
||||
prototest.AssertElementsMatch(t, []*pbresource.ID{compDest.Id}, cachedCompDestIDs)
|
||||
})
|
||||
|
||||
compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name).
|
||||
resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name).
|
||||
WithData(suite.T(), suite.webComputedDestinationsData).
|
||||
WithTenancy(tenancy).
|
||||
Write(suite.T(), suite.client)
|
||||
|
@ -408,17 +252,11 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
require.NotNil(suite.T(), api1ComputedRoutes)
|
||||
|
||||
// This destination points to TCP, but the computed routes is stale and only knows about HTTP.
|
||||
destinations, err := f.FetchComputedExplicitDestinationsData(suite.ctx, suite.webProxy.Id, suite.proxyCfg)
|
||||
destinations, err := fetchComputedExplicitDestinationsData(suite.rt, webWrk, mgwMode)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check that we didn't return any destinations.
|
||||
require.Nil(t, destinations)
|
||||
|
||||
// Check that destination service is still in cache because it's still referenced from the pbmesh.Destinations
|
||||
// resource.
|
||||
cachedCompDestIDs := c.ComputedDestinationsByService(resource.IDFromReference(api1ServiceRef))
|
||||
compDest.Id.Uid = ""
|
||||
prototest.AssertElementsMatch(t, []*pbresource.ID{compDest.Id}, cachedCompDestIDs)
|
||||
})
|
||||
|
||||
testutil.RunStep(suite.T(), "happy path", func(t *testing.T) {
|
||||
|
@ -436,8 +274,6 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
)
|
||||
require.NotNil(suite.T(), api2ComputedRoutes)
|
||||
|
||||
resourcetest.ResourceID(suite.api1Service.Id)
|
||||
|
||||
expectedDestinations := []*intermediate.Destination{
|
||||
{
|
||||
Explicit: suite.webComputedDestinationsData.Destinations[0],
|
||||
|
@ -445,13 +281,11 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
ComputedPortRoutes: routestest.MutateTargets(suite.T(), api1ComputedRoutes.Data, "tcp", func(t *testing.T, details *pbmesh.BackendTargetDetails) {
|
||||
switch {
|
||||
case resource.ReferenceOrIDMatch(suite.api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp":
|
||||
se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api1ServiceEndpoints)
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: se.Resource.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, suite.api1Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = se.Data
|
||||
details.IdentityRefs = []*pbresource.Reference{{
|
||||
Name: "api-1-identity",
|
||||
Tenancy: suite.api1Service.Id.Tenancy,
|
||||
|
@ -465,13 +299,11 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
ComputedPortRoutes: routestest.MutateTargets(suite.T(), api2ComputedRoutes.Data, "tcp1", func(t *testing.T, details *pbmesh.BackendTargetDetails) {
|
||||
switch {
|
||||
case resource.ReferenceOrIDMatch(suite.api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp1":
|
||||
se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api2ServiceEndpoints)
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: se.Resource.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, suite.api2Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = se.Data
|
||||
details.IdentityRefs = []*pbresource.Reference{{
|
||||
Name: "api-2-identity",
|
||||
Tenancy: suite.api2Service.Id.Tenancy,
|
||||
|
@ -485,13 +317,11 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
ComputedPortRoutes: routestest.MutateTargets(suite.T(), api2ComputedRoutes.Data, "tcp2", func(t *testing.T, details *pbmesh.BackendTargetDetails) {
|
||||
switch {
|
||||
case resource.ReferenceOrIDMatch(suite.api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2":
|
||||
se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api2ServiceEndpoints)
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: se.Resource.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, suite.api2Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = se.Data
|
||||
details.IdentityRefs = []*pbresource.Reference{{
|
||||
Name: "api-2-identity",
|
||||
Tenancy: suite.api2Service.Id.Tenancy,
|
||||
|
@ -501,7 +331,7 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
},
|
||||
}
|
||||
|
||||
actualDestinations, err := f.FetchComputedExplicitDestinationsData(suite.ctx, suite.webProxy.Id, suite.proxyCfg)
|
||||
actualDestinations, err := fetchComputedExplicitDestinationsData(suite.rt, webWrk, mgwMode)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check that we've computed expanded destinations correctly.
|
||||
|
@ -511,40 +341,17 @@ func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() {
|
|||
}
|
||||
|
||||
func (suite *dataFetcherSuite) TestFetcher_FetchImplicitDestinationsData() {
|
||||
const mgwMode = pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_NONE
|
||||
|
||||
suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) {
|
||||
webWrk := resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), suite.webWorkload)
|
||||
|
||||
// Create a few other services to be implicit upstreams.
|
||||
api3Service := resourcetest.Resource(pbcatalog.ServiceType, "api-3").
|
||||
WithData(suite.T(), &pbcatalog.Service{
|
||||
VirtualIps: []string{"192.1.1.1"},
|
||||
Ports: []*pbcatalog.ServicePort{
|
||||
api3Service, _, _ := suite.createService(
|
||||
"api-3", tenancy, "api3", []*pbcatalog.ServicePort{
|
||||
{TargetPort: "tcp", VirtualPort: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
{TargetPort: "mesh", VirtualPort: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
},
|
||||
}).
|
||||
WithTenancy(tenancy).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
api3ServiceEndpointsData := &pbcatalog.ServiceEndpoints{
|
||||
Endpoints: []*pbcatalog.Endpoint{
|
||||
{
|
||||
TargetRef: &pbresource.ID{
|
||||
Name: "api-3-abc",
|
||||
Tenancy: api3Service.Id.Tenancy,
|
||||
Type: pbcatalog.WorkloadType,
|
||||
},
|
||||
Addresses: []*pbcatalog.WorkloadAddress{{Host: "10.0.0.1"}},
|
||||
Ports: map[string]*pbcatalog.WorkloadPort{
|
||||
"tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP},
|
||||
"mesh": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_MESH},
|
||||
},
|
||||
Identity: "api-3-identity",
|
||||
},
|
||||
},
|
||||
}
|
||||
api3ServiceEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-3").
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), api3ServiceEndpointsData).
|
||||
Write(suite.T(), suite.client)
|
||||
}, []string{"192.1.1.1"}, []string{"api-3-identity"}, false)
|
||||
|
||||
// Write a default ComputedRoutes for api1, api2, and api3.
|
||||
var (
|
||||
|
@ -565,6 +372,25 @@ func (suite *dataFetcherSuite) TestFetcher_FetchImplicitDestinationsData() {
|
|||
)
|
||||
require.NotNil(suite.T(), api3ComputedRoutes)
|
||||
|
||||
cidID := &pbresource.ID{
|
||||
Type: pbmesh.ComputedImplicitDestinationsType,
|
||||
Tenancy: webWrk.Id.Tenancy,
|
||||
Name: webWrk.Data.Identity,
|
||||
}
|
||||
|
||||
// Write a CID that grants web-id-abc access to api-3-identity
|
||||
resourcetest.ResourceID(cidID).
|
||||
WithTenancy(tenancy).
|
||||
WithData(suite.T(), &pbmesh.ComputedImplicitDestinations{
|
||||
Destinations: []*pbmesh.ImplicitDestination{
|
||||
{
|
||||
DestinationRef: resource.Reference(api3Service.Id, ""),
|
||||
DestinationPorts: []string{"tcp"},
|
||||
},
|
||||
},
|
||||
}).
|
||||
Write(suite.T(), suite.client)
|
||||
|
||||
existingDestinations := []*intermediate.Destination{
|
||||
{
|
||||
Explicit: suite.webComputedDestinationsData.Destinations[0],
|
||||
|
@ -572,13 +398,11 @@ func (suite *dataFetcherSuite) TestFetcher_FetchImplicitDestinationsData() {
|
|||
ComputedPortRoutes: routestest.MutateTargets(suite.T(), api1ComputedRoutes.Data, "tcp", func(t *testing.T, details *pbmesh.BackendTargetDetails) {
|
||||
switch {
|
||||
case resource.ReferenceOrIDMatch(suite.api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp":
|
||||
se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api1ServiceEndpoints)
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: se.Resource.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, suite.api1Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = se.Data
|
||||
details.IdentityRefs = []*pbresource.Reference{{
|
||||
Name: "api-1-identity",
|
||||
Tenancy: suite.api1Service.Id.Tenancy,
|
||||
|
@ -592,13 +416,11 @@ func (suite *dataFetcherSuite) TestFetcher_FetchImplicitDestinationsData() {
|
|||
ComputedPortRoutes: routestest.MutateTargets(suite.T(), api2ComputedRoutes.Data, "tcp1", func(t *testing.T, details *pbmesh.BackendTargetDetails) {
|
||||
switch {
|
||||
case resource.ReferenceOrIDMatch(suite.api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp1":
|
||||
se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api2ServiceEndpoints)
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: se.Resource.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, suite.api2Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = se.Data
|
||||
details.IdentityRefs = []*pbresource.Reference{{
|
||||
Name: "api-2-identity",
|
||||
Tenancy: suite.api1Service.Id.Tenancy,
|
||||
|
@ -612,13 +434,11 @@ func (suite *dataFetcherSuite) TestFetcher_FetchImplicitDestinationsData() {
|
|||
ComputedPortRoutes: routestest.MutateTargets(suite.T(), api2ComputedRoutes.Data, "tcp2", func(t *testing.T, details *pbmesh.BackendTargetDetails) {
|
||||
switch {
|
||||
case resource.ReferenceOrIDMatch(suite.api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2":
|
||||
se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api2ServiceEndpoints)
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: se.Resource.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, suite.api2Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = se.Data
|
||||
details.IdentityRefs = []*pbresource.Reference{{
|
||||
Name: "api-2-identity",
|
||||
Tenancy: suite.api1Service.Id.Tenancy,
|
||||
|
@ -626,19 +446,24 @@ func (suite *dataFetcherSuite) TestFetcher_FetchImplicitDestinationsData() {
|
|||
}
|
||||
}),
|
||||
},
|
||||
{
|
||||
}
|
||||
|
||||
actualDestinations, err := fetchComputedImplicitDestinationsData(
|
||||
suite.rt, webWrk, mgwMode, slices.Clone(existingDestinations),
|
||||
)
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
existingDestinations = append(existingDestinations, &intermediate.Destination{
|
||||
// implicit
|
||||
Service: resourcetest.MustDecode[*pbcatalog.Service](suite.T(), api3Service),
|
||||
ComputedPortRoutes: routestest.MutateTargets(suite.T(), api3ComputedRoutes.Data, "tcp", func(t *testing.T, details *pbmesh.BackendTargetDetails) {
|
||||
switch {
|
||||
case resource.ReferenceOrIDMatch(api3Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp":
|
||||
se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), api3ServiceEndpoints)
|
||||
details.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: se.Resource.Id,
|
||||
Id: resource.ReplaceType(pbcatalog.ServiceEndpointsType, api3Service.Id),
|
||||
MeshPort: details.MeshPort,
|
||||
RoutePort: details.BackendRef.Port,
|
||||
}
|
||||
details.ServiceEndpoints = se.Data
|
||||
details.IdentityRefs = []*pbresource.Reference{{
|
||||
Name: "api-3-identity",
|
||||
Tenancy: suite.api1Service.Id.Tenancy,
|
||||
|
@ -646,16 +471,7 @@ func (suite *dataFetcherSuite) TestFetcher_FetchImplicitDestinationsData() {
|
|||
}
|
||||
}),
|
||||
VirtualIPs: []string{"192.1.1.1"},
|
||||
},
|
||||
}
|
||||
|
||||
f := Fetcher{
|
||||
client: suite.client,
|
||||
}
|
||||
|
||||
actualDestinations, err := f.FetchImplicitDestinationsData(context.Background(), suite.webProxy.Id, existingDestinations)
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
})
|
||||
prototest.AssertElementsMatch(suite.T(), existingDestinations, actualDestinations)
|
||||
})
|
||||
}
|
||||
|
@ -669,12 +485,10 @@ func (suite *dataFetcherSuite) appendTenancyInfo(tenancy *pbresource.Tenancy) st
|
|||
}
|
||||
|
||||
func (suite *dataFetcherSuite) cleanUpNodes() {
|
||||
suite.resourceClient.MustDelete(suite.T(), suite.api1Service.Id)
|
||||
suite.resourceClient.MustDelete(suite.T(), suite.api1ServiceEndpoints.Id)
|
||||
suite.resourceClient.MustDelete(suite.T(), suite.api2Service.Id)
|
||||
suite.resourceClient.MustDelete(suite.T(), suite.api2ServiceEndpoints.Id)
|
||||
suite.resourceClient.MustDelete(suite.T(), suite.webProxy.Id)
|
||||
suite.resourceClient.MustDelete(suite.T(), suite.webWorkload.Id)
|
||||
suite.client.MustDelete(suite.T(), suite.api1Service.Id)
|
||||
suite.client.MustDelete(suite.T(), suite.api2Service.Id)
|
||||
suite.client.MustDelete(suite.T(), suite.webProxy.Id)
|
||||
suite.client.MustDelete(suite.T(), suite.webWorkload.Id)
|
||||
}
|
||||
|
||||
func (suite *dataFetcherSuite) runTestCaseWithTenancies(t func(*pbresource.Tenancy)) {
|
||||
|
@ -688,3 +502,15 @@ func (suite *dataFetcherSuite) runTestCaseWithTenancies(t func(*pbresource.Tenan
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *dataFetcherSuite) createService(
|
||||
name string,
|
||||
tenancy *pbresource.Tenancy,
|
||||
exactSelector string,
|
||||
ports []*pbcatalog.ServicePort,
|
||||
vips []string,
|
||||
workloadIdentities []string,
|
||||
deferStatusUpdate bool,
|
||||
) (*pbresource.Resource, *pbcatalog.Service, func() *pbresource.Resource) {
|
||||
return createService(suite.T(), suite.client, name, tenancy, exactSelector, ports, vips, workloadIdentities, deferStatusUpdate)
|
||||
}
|
|
@ -1,461 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package fetcher
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/meshgateways"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
intermediateTypes "github.com/hashicorp/consul/internal/mesh/internal/types/intermediate"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
"github.com/hashicorp/consul/internal/storage"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
)
|
||||
|
||||
type Fetcher struct {
|
||||
client pbresource.ResourceServiceClient
|
||||
cache *cache.Cache
|
||||
}
|
||||
|
||||
func New(client pbresource.ResourceServiceClient, cache *cache.Cache) *Fetcher {
|
||||
return &Fetcher{
|
||||
client: client,
|
||||
cache: cache,
|
||||
}
|
||||
}
|
||||
|
||||
// FetchWorkload fetches a service resource from the resource service.
|
||||
// This will panic if the type field in the ID argument is not a Workload type.
|
||||
func (f *Fetcher) FetchWorkload(ctx context.Context, id *pbresource.ID) (*types.DecodedWorkload, error) {
|
||||
assertResourceType(pbcatalog.WorkloadType, id.Type)
|
||||
dec, err := resource.GetDecodedResource[*pbcatalog.Workload](ctx, f.client, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if dec == nil {
|
||||
// We also need to make sure to delete the associated proxy from cache.
|
||||
f.cache.UntrackWorkload(id)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
f.cache.TrackWorkload(dec)
|
||||
|
||||
return dec, err
|
||||
}
|
||||
|
||||
// FetchProxyStateTemplate fetches a service resource from the resource service.
|
||||
// This will panic if the type field in the ID argument is not a ProxyStateTemplate type.
|
||||
func (f *Fetcher) FetchProxyStateTemplate(ctx context.Context, id *pbresource.ID) (*types.DecodedProxyStateTemplate, error) {
|
||||
assertResourceType(pbmesh.ProxyStateTemplateType, id.Type)
|
||||
return resource.GetDecodedResource[*pbmesh.ProxyStateTemplate](ctx, f.client, id)
|
||||
}
|
||||
|
||||
// FetchComputedTrafficPermissions fetches a service resource from the resource service.
|
||||
// This will panic if the type field in the ID argument is not a ComputedTrafficPermissons type.
|
||||
func (f *Fetcher) FetchComputedTrafficPermissions(ctx context.Context, id *pbresource.ID) (*types.DecodedComputedTrafficPermissions, error) {
|
||||
assertResourceType(pbauth.ComputedTrafficPermissionsType, id.Type)
|
||||
return resource.GetDecodedResource[*pbauth.ComputedTrafficPermissions](ctx, f.client, id)
|
||||
}
|
||||
|
||||
// FetchServiceEndpoints fetches a service resource from the resource service.
|
||||
// This will panic if the type field in the ID argument is not a ServiceEndpoints type.
|
||||
func (f *Fetcher) FetchServiceEndpoints(ctx context.Context, id *pbresource.ID) (*types.DecodedServiceEndpoints, error) {
|
||||
assertResourceType(pbcatalog.ServiceEndpointsType, id.Type)
|
||||
return resource.GetDecodedResource[*pbcatalog.ServiceEndpoints](ctx, f.client, id)
|
||||
}
|
||||
|
||||
// FetchService fetches a service resource from the resource service.
|
||||
// This will panic if the type field in the ID argument is not a Service type.
|
||||
func (f *Fetcher) FetchService(ctx context.Context, id *pbresource.ID) (*types.DecodedService, error) {
|
||||
assertResourceType(pbcatalog.ServiceType, id.Type)
|
||||
return resource.GetDecodedResource[*pbcatalog.Service](ctx, f.client, id)
|
||||
}
|
||||
|
||||
// FetchDestinations fetches a service resource from the resource service.
|
||||
// This will panic if the type field in the ID argument is not a Destinations type.
|
||||
func (f *Fetcher) FetchDestinations(ctx context.Context, id *pbresource.ID) (*types.DecodedDestinations, error) {
|
||||
assertResourceType(pbmesh.DestinationsType, id.Type)
|
||||
return resource.GetDecodedResource[*pbmesh.Destinations](ctx, f.client, id)
|
||||
}
|
||||
|
||||
// FetchComputedRoutes fetches a service resource from the resource service.
|
||||
// This will panic if the type field in the ID argument is not a ComputedRoutes type.
|
||||
func (f *Fetcher) FetchComputedRoutes(ctx context.Context, id *pbresource.ID) (*types.DecodedComputedRoutes, error) {
|
||||
assertResourceType(pbmesh.ComputedRoutesType, id.Type)
|
||||
if !types.IsComputedRoutesType(id.Type) {
|
||||
return nil, fmt.Errorf("id must be a ComputedRoutes type")
|
||||
}
|
||||
|
||||
dec, err := resource.GetDecodedResource[*pbmesh.ComputedRoutes](ctx, f.client, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if dec == nil {
|
||||
f.cache.UntrackComputedRoutes(id)
|
||||
}
|
||||
|
||||
return dec, err
|
||||
}
|
||||
|
||||
func (f *Fetcher) FetchComputedExplicitDestinationsData(
|
||||
ctx context.Context,
|
||||
proxyID *pbresource.ID,
|
||||
proxyCfg *pbmesh.ComputedProxyConfiguration,
|
||||
) ([]*intermediateTypes.Destination, error) {
|
||||
var destinations []*intermediateTypes.Destination
|
||||
|
||||
// Fetch computed explicit destinations first.
|
||||
cdID := resource.ReplaceType(pbmesh.ComputedExplicitDestinationsType, proxyID)
|
||||
cd, err := resource.GetDecodedResource[*pbmesh.ComputedExplicitDestinations](ctx, f.client, cdID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cd == nil {
|
||||
f.cache.UntrackComputedDestinations(cdID)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Otherwise, track this resource in the destinations cache.
|
||||
f.cache.TrackComputedDestinations(cd)
|
||||
|
||||
for _, dest := range cd.GetData().GetDestinations() {
|
||||
d := &intermediateTypes.Destination{}
|
||||
|
||||
serviceID := resource.IDFromReference(dest.DestinationRef)
|
||||
|
||||
// Fetch Service
|
||||
svc, err := f.FetchService(ctx, serviceID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if svc == nil {
|
||||
// If the Service resource is not found, skip this destination.
|
||||
continue
|
||||
}
|
||||
|
||||
d.Service = svc
|
||||
|
||||
// Check if this service is mesh-enabled. If not, update the status.
|
||||
if !svc.GetData().IsMeshEnabled() {
|
||||
// This error should not cause the execution to stop, as we want to make sure that this non-mesh destination
|
||||
// service gets removed from the proxy state.
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if the desired port exists on the service and skip it doesn't.
|
||||
if svc.GetData().FindPortByID(dest.DestinationPort) == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// No destination port should point to a port with "mesh" protocol,
|
||||
// so check if destination port has the mesh protocol and skip it if it does.
|
||||
if svc.GetData().FindPortByID(dest.DestinationPort).GetProtocol() == pbcatalog.Protocol_PROTOCOL_MESH {
|
||||
continue
|
||||
}
|
||||
|
||||
// Fetch ComputedRoutes.
|
||||
cr, err := f.FetchComputedRoutes(ctx, resource.ReplaceType(pbmesh.ComputedRoutesType, serviceID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if cr == nil {
|
||||
// This is required, so wait until it exists.
|
||||
continue
|
||||
}
|
||||
|
||||
portConfig, ok := cr.Data.PortedConfigs[dest.DestinationPort]
|
||||
if !ok {
|
||||
// This is required, so wait until it exists.
|
||||
continue
|
||||
}
|
||||
|
||||
// Copy this so we can mutate the targets.
|
||||
d.ComputedPortRoutes = proto.Clone(portConfig).(*pbmesh.ComputedPortRoutes)
|
||||
|
||||
// As Destinations resource contains a list of destinations,
|
||||
// we need to find the one that references our service and port.
|
||||
d.Explicit = dest
|
||||
|
||||
// NOTE: we collect both DIRECT and INDIRECT target information here.
|
||||
for _, routeTarget := range d.ComputedPortRoutes.Targets {
|
||||
targetServiceID := resource.IDFromReference(routeTarget.BackendRef.Ref)
|
||||
|
||||
// Fetch ServiceEndpoints.
|
||||
serviceEndpointID := resource.ReplaceType(pbcatalog.ServiceEndpointsType, targetServiceID)
|
||||
se, err := f.FetchServiceEndpoints(ctx, serviceEndpointID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if se != nil {
|
||||
routeTarget.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: se.Id,
|
||||
MeshPort: routeTarget.MeshPort,
|
||||
RoutePort: routeTarget.BackendRef.Port,
|
||||
}
|
||||
routeTarget.ServiceEndpoints = se.Data
|
||||
// Gather all identities.
|
||||
var identities []*pbresource.Reference
|
||||
for _, identity := range se.GetData().GetIdentities() {
|
||||
identities = append(identities, &pbresource.Reference{
|
||||
Name: identity,
|
||||
Tenancy: se.Resource.Id.Tenancy,
|
||||
})
|
||||
}
|
||||
routeTarget.IdentityRefs = identities
|
||||
}
|
||||
|
||||
// If the target service is in a different partition and the mesh gateway mode is
|
||||
// "local" or "remote", use the ServiceEndpoints for the corresponding MeshGateway
|
||||
// instead of the ServiceEndpoints for the target service. The IdentityRefs on the
|
||||
// target will remain the same for TCP targets.
|
||||
//
|
||||
// TODO(nathancoleman) Consider cross-datacenter case as well
|
||||
if routeTarget.BackendRef.Ref.Tenancy.Partition != proxyID.Tenancy.Partition {
|
||||
mode := pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_NONE
|
||||
if proxyCfg != nil && proxyCfg.DynamicConfig != nil {
|
||||
mode = proxyCfg.GetDynamicConfig().GetMeshGatewayMode()
|
||||
}
|
||||
|
||||
switch mode {
|
||||
case pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_LOCAL:
|
||||
// Use ServiceEndpoints for the MeshGateway in the source service's partition
|
||||
routeTarget.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: &pbresource.ID{
|
||||
Type: pbcatalog.ServiceEndpointsType,
|
||||
Name: meshgateways.GatewayName,
|
||||
Tenancy: proxyID.Tenancy,
|
||||
},
|
||||
MeshPort: meshgateways.LANPortName,
|
||||
RoutePort: meshgateways.LANPortName,
|
||||
}
|
||||
|
||||
se, err := f.FetchServiceEndpoints(ctx, routeTarget.ServiceEndpointsRef.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if se != nil {
|
||||
routeTarget.ServiceEndpoints = se.GetData()
|
||||
}
|
||||
case pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_REMOTE:
|
||||
// Use ServiceEndpoints for the MeshGateway in the target service's partition
|
||||
routeTarget.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: &pbresource.ID{
|
||||
Type: pbcatalog.ServiceEndpointsType,
|
||||
Name: meshgateways.GatewayName,
|
||||
Tenancy: targetServiceID.Tenancy,
|
||||
},
|
||||
MeshPort: meshgateways.WANPortName,
|
||||
RoutePort: meshgateways.WANPortName,
|
||||
}
|
||||
|
||||
se, err := f.FetchServiceEndpoints(ctx, routeTarget.ServiceEndpointsRef.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if se != nil {
|
||||
routeTarget.ServiceEndpoints = se.GetData()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destinations = append(destinations, d)
|
||||
}
|
||||
|
||||
return destinations, nil
|
||||
}
|
||||
|
||||
type PortReferenceKey struct {
|
||||
resource.ReferenceKey
|
||||
Port string
|
||||
}
|
||||
|
||||
// FetchImplicitDestinationsData fetches all implicit destinations and adds them to existing destinations.
|
||||
// If the implicit destination is already in addToDestinations, it will be skipped.
|
||||
// todo (ishustava): this function will eventually need to fetch implicit destinations from the ImplicitDestinations resource instead.
|
||||
func (f *Fetcher) FetchImplicitDestinationsData(
|
||||
ctx context.Context,
|
||||
proxyID *pbresource.ID,
|
||||
addToDestinations []*intermediateTypes.Destination,
|
||||
) ([]*intermediateTypes.Destination, error) {
|
||||
// First, convert existing destinations to a map so we can de-dup.
|
||||
//
|
||||
// This is keyed by the serviceID+port of the upstream, which is effectively
|
||||
// the same as the id of the computed routes for the service.
|
||||
destinations := make(map[PortReferenceKey]*intermediateTypes.Destination)
|
||||
for _, d := range addToDestinations {
|
||||
prk := PortReferenceKey{
|
||||
ReferenceKey: resource.NewReferenceKey(d.Service.Resource.Id),
|
||||
Port: d.ComputedPortRoutes.ParentRef.Port,
|
||||
}
|
||||
destinations[prk] = d
|
||||
}
|
||||
|
||||
// For now we need to look up all computed routes within a partition.
|
||||
rsp, err := f.client.List(ctx, &pbresource.ListRequest{
|
||||
Type: pbmesh.ComputedRoutesType,
|
||||
Tenancy: &pbresource.Tenancy{
|
||||
Namespace: storage.Wildcard,
|
||||
Partition: proxyID.Tenancy.Partition,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, r := range rsp.Resources {
|
||||
svcID := resource.ReplaceType(pbcatalog.ServiceType, r.Id)
|
||||
computedRoutes, err := resource.Decode[*pbmesh.ComputedRoutes](r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if computedRoutes == nil {
|
||||
// the routes-controller doesn't deem this worthy of the mesh
|
||||
continue
|
||||
}
|
||||
|
||||
// Fetch the service.
|
||||
// todo (ishustava): this should eventually grab virtual IPs resource.
|
||||
svc, err := f.FetchService(ctx, resource.ReplaceType(pbcatalog.ServiceType, r.Id))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if svc == nil {
|
||||
// If service no longer exists, skip.
|
||||
continue
|
||||
}
|
||||
|
||||
// If this proxy is a part of this service, ignore it.
|
||||
if isPartOfService(resource.ReplaceType(pbcatalog.WorkloadType, proxyID), svc) {
|
||||
continue
|
||||
}
|
||||
|
||||
inMesh := false
|
||||
for _, port := range svc.Data.Ports {
|
||||
if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH {
|
||||
inMesh = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !inMesh {
|
||||
// If a service is no longer in the mesh, skip.
|
||||
continue
|
||||
}
|
||||
|
||||
// Fetch the resources that may show up duplicated.
|
||||
//
|
||||
// NOTE: we collect both DIRECT and INDIRECT target information here.
|
||||
endpointsMap := make(map[resource.ReferenceKey]*types.DecodedServiceEndpoints)
|
||||
for _, portConfig := range computedRoutes.Data.PortedConfigs {
|
||||
for _, routeTarget := range portConfig.Targets {
|
||||
targetServiceID := resource.IDFromReference(routeTarget.BackendRef.Ref)
|
||||
|
||||
seID := resource.ReplaceType(pbcatalog.ServiceEndpointsType, targetServiceID)
|
||||
seRK := resource.NewReferenceKey(seID)
|
||||
|
||||
if _, ok := endpointsMap[seRK]; !ok {
|
||||
se, err := f.FetchServiceEndpoints(ctx, seID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// We only add the endpoint to the map if it's not nil. If it's missing on lookup now, the
|
||||
// controller should get triggered when the endpoint exists again since it watches service
|
||||
// endpoints.
|
||||
if se != nil {
|
||||
endpointsMap[seRK] = se
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for portName, portConfig := range computedRoutes.Data.PortedConfigs {
|
||||
// If it's already in destinations, ignore it.
|
||||
prk := PortReferenceKey{
|
||||
ReferenceKey: resource.NewReferenceKey(svcID),
|
||||
Port: portName,
|
||||
}
|
||||
if _, ok := destinations[prk]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// Copy this so we can mutate the targets.
|
||||
portConfig = proto.Clone(portConfig).(*pbmesh.ComputedPortRoutes)
|
||||
|
||||
d := &intermediateTypes.Destination{
|
||||
Service: svc,
|
||||
ComputedPortRoutes: portConfig,
|
||||
VirtualIPs: svc.Data.VirtualIps,
|
||||
}
|
||||
for _, routeTarget := range portConfig.Targets {
|
||||
targetServiceID := resource.IDFromReference(routeTarget.BackendRef.Ref)
|
||||
seID := resource.ReplaceType(pbcatalog.ServiceEndpointsType, targetServiceID)
|
||||
|
||||
// Fetch ServiceEndpoints.
|
||||
se, ok := endpointsMap[resource.NewReferenceKey(seID)]
|
||||
if ok {
|
||||
routeTarget.ServiceEndpointsRef = &pbproxystate.EndpointRef{
|
||||
Id: se.Resource.Id,
|
||||
MeshPort: routeTarget.MeshPort,
|
||||
RoutePort: routeTarget.BackendRef.Port,
|
||||
}
|
||||
routeTarget.ServiceEndpoints = se.Data
|
||||
|
||||
// Gather all identities.
|
||||
var identities []*pbresource.Reference
|
||||
for _, ep := range se.Data.Endpoints {
|
||||
identities = append(identities, &pbresource.Reference{
|
||||
Name: ep.Identity,
|
||||
Tenancy: se.Resource.Id.Tenancy,
|
||||
})
|
||||
}
|
||||
routeTarget.IdentityRefs = identities
|
||||
}
|
||||
}
|
||||
addToDestinations = append(addToDestinations, d)
|
||||
}
|
||||
}
|
||||
return addToDestinations, err
|
||||
}
|
||||
|
||||
// FetchComputedProxyConfiguration fetches proxy configurations for the proxy state template provided by id
|
||||
// and merges them into one object.
|
||||
func (f *Fetcher) FetchComputedProxyConfiguration(ctx context.Context, id *pbresource.ID) (*types.DecodedComputedProxyConfiguration, error) {
|
||||
compProxyCfgID := resource.ReplaceType(pbmesh.ComputedProxyConfigurationType, id)
|
||||
|
||||
return resource.GetDecodedResource[*pbmesh.ComputedProxyConfiguration](ctx, f.client, compProxyCfgID)
|
||||
}
|
||||
|
||||
func isPartOfService(workloadID *pbresource.ID, svc *types.DecodedService) bool {
|
||||
if !resource.EqualTenancy(workloadID.GetTenancy(), svc.Resource.Id.GetTenancy()) {
|
||||
return false
|
||||
}
|
||||
sel := svc.Data.Workloads
|
||||
for _, exact := range sel.GetNames() {
|
||||
if workloadID.GetName() == exact {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, prefix := range sel.GetPrefixes() {
|
||||
if strings.HasPrefix(workloadID.GetName(), prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func assertResourceType(expected, actual *pbresource.Type) {
|
||||
if !proto.Equal(expected, actual) {
|
||||
// this is always a programmer error so safe to panic
|
||||
panic(fmt.Sprintf("expected a query for a type of %q, you provided a type of %q", expected, actual))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package sidecarproxy
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/internal/catalog"
|
||||
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
"github.com/hashicorp/consul/sdk/testutil"
|
||||
)
|
||||
|
||||
func createService(
|
||||
t *testing.T,
|
||||
client *resourcetest.Client,
|
||||
name string,
|
||||
tenancy *pbresource.Tenancy,
|
||||
exactSelector string,
|
||||
ports []*pbcatalog.ServicePort,
|
||||
vips []string,
|
||||
workloadIdentities []string,
|
||||
deferStatusUpdate bool,
|
||||
) (*pbresource.Resource, *pbcatalog.Service, func() *pbresource.Resource) {
|
||||
data := &pbcatalog.Service{
|
||||
Workloads: &pbcatalog.WorkloadSelector{
|
||||
Names: []string{exactSelector},
|
||||
},
|
||||
Ports: ports,
|
||||
VirtualIps: vips,
|
||||
}
|
||||
|
||||
var status *pbresource.Status
|
||||
if deferStatusUpdate {
|
||||
status = &pbresource.Status{
|
||||
Conditions: []*pbresource.Condition{{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: "",
|
||||
}},
|
||||
}
|
||||
} else {
|
||||
status = &pbresource.Status{
|
||||
Conditions: []*pbresource.Condition{{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: strings.Join(workloadIdentities, ","),
|
||||
}},
|
||||
}
|
||||
}
|
||||
|
||||
res := resourcetest.Resource(pbcatalog.ServiceType, name).
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, data).
|
||||
WithStatus(catalog.EndpointsStatusKey, status).
|
||||
Write(t, client)
|
||||
|
||||
var statusUpdate = func() *pbresource.Resource { return res }
|
||||
if deferStatusUpdate {
|
||||
statusUpdate = func() *pbresource.Resource {
|
||||
ctx := testutil.TestContext(t)
|
||||
|
||||
status := &pbresource.Status{
|
||||
ObservedGeneration: res.Generation,
|
||||
Conditions: []*pbresource.Condition{{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: strings.Join(workloadIdentities, ","),
|
||||
}},
|
||||
}
|
||||
resp, err := client.WriteStatus(ctx, &pbresource.WriteStatusRequest{
|
||||
Id: res.Id,
|
||||
Key: catalog.EndpointsStatusKey,
|
||||
Status: status,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return resp.Resource
|
||||
}
|
||||
}
|
||||
|
||||
return res, data, statusUpdate
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package sidecarproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/controller/cache"
|
||||
"github.com/hashicorp/consul/internal/controller/cache/indexers"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/meshindexes"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
)
|
||||
|
||||
const (
|
||||
selectedWorkloadsIndexName = "selected-workloads"
|
||||
)
|
||||
|
||||
// Cache: reverse CED => Service(destination)
|
||||
var computedExplicitDestinationsByServiceIndex = indexers.RefOrIDIndex(
|
||||
"computed-explicit-destinations-by-service",
|
||||
func(ced *types.DecodedComputedExplicitDestinations) []*pbresource.Reference {
|
||||
if len(ced.Data.Destinations) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := make([]*pbresource.Reference, 0, len(ced.Data.Destinations))
|
||||
for _, dest := range ced.Data.Destinations {
|
||||
if resource.EqualType(pbcatalog.ServiceType, dest.DestinationRef.Type) {
|
||||
out = append(out, dest.DestinationRef)
|
||||
}
|
||||
}
|
||||
return out
|
||||
},
|
||||
)
|
||||
|
||||
// Cache: reverse CID => Service(destination)
|
||||
var computedImplicitDestinationsByServiceIndex = indexers.RefOrIDIndex(
|
||||
"computed-implicit-destinations-by-service",
|
||||
func(ced *types.DecodedComputedImplicitDestinations) []*pbresource.Reference {
|
||||
if len(ced.Data.Destinations) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := make([]*pbresource.Reference, 0, len(ced.Data.Destinations))
|
||||
for _, dest := range ced.Data.Destinations {
|
||||
if resource.EqualType(pbcatalog.ServiceType, dest.DestinationRef.Type) {
|
||||
out = append(out, dest.DestinationRef)
|
||||
}
|
||||
}
|
||||
return out
|
||||
},
|
||||
)
|
||||
|
||||
// Cache: reverse Workload => WorkloadIdentity
|
||||
var workloadByWorkloadIdentityIndex = indexers.RefOrIDIndex(
|
||||
"workload-by-workload-identity",
|
||||
func(wrk *types.DecodedWorkload) []*pbresource.Reference {
|
||||
if wrk.Data.Identity == "" {
|
||||
return nil
|
||||
}
|
||||
wid := &pbresource.Reference{
|
||||
Type: pbauth.WorkloadIdentityType,
|
||||
Tenancy: wrk.GetId().GetTenancy(),
|
||||
Name: wrk.Data.Identity,
|
||||
}
|
||||
return []*pbresource.Reference{wid}
|
||||
},
|
||||
)
|
||||
|
||||
// Cache: reverse CR => SVC[backend]
|
||||
var computedRoutesByBackendServiceIndex = meshindexes.ComputedRoutesByBackendServiceIndex()
|
||||
|
||||
// Cache: reverse SVC[*] => WI[*]
|
||||
var serviceByWorkloadIdentityIndex = meshindexes.ServiceByWorkloadIdentityIndex()
|
||||
|
||||
func MapComputedImplicitDestinations(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) {
|
||||
assertResourceType(pbmesh.ComputedImplicitDestinationsType, res.Id.Type)
|
||||
|
||||
wiID := resource.ReplaceType(pbauth.WorkloadIdentityType, res.Id)
|
||||
|
||||
workloads, err := rt.Cache.List(pbcatalog.WorkloadType, workloadByWorkloadIdentityIndex.Name(), wiID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return controller.MakeRequestsFromResources(pbmesh.ProxyStateTemplateType, workloads), nil
|
||||
}
|
||||
|
||||
func MapComputedTrafficPermissions(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) {
|
||||
assertResourceType(pbauth.ComputedTrafficPermissionsType, res.Id.Type)
|
||||
|
||||
wiID := resource.ReplaceType(pbauth.WorkloadIdentityType, res.Id)
|
||||
|
||||
workloads, err := rt.Cache.List(pbcatalog.WorkloadType, workloadByWorkloadIdentityIndex.Name(), wiID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return controller.MakeRequestsFromResources(pbmesh.ProxyStateTemplateType, workloads), nil
|
||||
}
|
||||
|
||||
func MapComputedRoutes(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) {
|
||||
assertResourceType(pbmesh.ComputedRoutesType, res.Id.Type)
|
||||
|
||||
svcID := resource.ReplaceType(pbcatalog.ServiceType, res.Id)
|
||||
|
||||
return mapServiceThroughDestinations(rt.Cache, svcID)
|
||||
}
|
||||
|
||||
func MapService(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) {
|
||||
assertResourceType(pbcatalog.ServiceType, res.Id.Type)
|
||||
|
||||
pstIDs, err := mapServiceThroughDestinations(rt.Cache, res.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Now walk the mesh configuration information backwards because
|
||||
// we need to find any PST that needs to DISCOVER endpoints for this
|
||||
// service as a part of mesh configuration and traffic routing.
|
||||
|
||||
// Find all ComputedRoutes that reference this service.
|
||||
computedRoutes, err := rt.Cache.List(
|
||||
pbmesh.ComputedRoutesType,
|
||||
computedRoutesByBackendServiceIndex.Name(),
|
||||
res.Id,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, cr := range computedRoutes {
|
||||
// Find all Upstreams that reference a Service aligned with this
|
||||
// ComputedRoutes. Afterwards, find all Workloads selected by the
|
||||
// Upstreams, and align a PST with those.
|
||||
|
||||
ids, err := MapComputedRoutes(ctx, rt, cr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pstIDs = append(pstIDs, ids...)
|
||||
}
|
||||
|
||||
return pstIDs, nil
|
||||
}
|
||||
|
||||
func mapServiceThroughDestinations(cache cache.ReadOnlyCache, svcID *pbresource.ID) ([]controller.Request, error) {
|
||||
explicitDests, err := cache.List(
|
||||
pbmesh.ComputedExplicitDestinationsType,
|
||||
computedExplicitDestinationsByServiceIndex.Name(),
|
||||
svcID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
implicitDests, err := cache.List(
|
||||
pbmesh.ComputedImplicitDestinationsType,
|
||||
computedImplicitDestinationsByServiceIndex.Name(),
|
||||
svcID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// NOTE: ComputedExplicitDestinations are name-aligned with ProxyStateTemplates.
|
||||
// This is different for implicit dests, as ComputedImplicitDestinations is name-aligned with WorkloadIdentity
|
||||
reqs := make([]controller.Request, 0, len(explicitDests)+len(implicitDests))
|
||||
reqs = append(reqs, controller.MakeRequestsFromResources(
|
||||
pbmesh.ProxyStateTemplateType,
|
||||
explicitDests,
|
||||
)...)
|
||||
|
||||
for _, dest := range implicitDests {
|
||||
wiID := resource.ReplaceType(pbauth.WorkloadIdentityType, dest.Id)
|
||||
|
||||
workloads, err := cache.List(
|
||||
pbcatalog.WorkloadType,
|
||||
workloadByWorkloadIdentityIndex.Name(),
|
||||
wiID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reqs = append(reqs, controller.MakeRequestsFromResources(
|
||||
pbmesh.ProxyStateTemplateType,
|
||||
workloads,
|
||||
)...)
|
||||
}
|
||||
|
||||
return reqs, nil
|
||||
}
|
||||
|
||||
func assertResourceType(expected, actual *pbresource.Type) {
|
||||
if !proto.Equal(expected, actual) {
|
||||
// this is always a programmer error so safe to panic
|
||||
panic(fmt.Sprintf("expected a query for a type of %q, you provided a type of %q", expected, actual))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package meshindexes
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/consul/internal/catalog"
|
||||
"github.com/hashicorp/consul/internal/controller/cache/index"
|
||||
"github.com/hashicorp/consul/internal/controller/cache/indexers"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
)
|
||||
|
||||
// Cache: reverse CR => SVC[backend]
|
||||
func ComputedRoutesByBackendServiceIndex() *index.Index {
|
||||
return indexers.RefOrIDIndex(
|
||||
"computed-routes-by-backend-service",
|
||||
func(cr *types.DecodedComputedRoutes) []*pbresource.Reference {
|
||||
return GetBackendServiceRefsFromComputedRoutes(cr)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func GetBackendServiceRefsFromComputedRoutes(cr *types.DecodedComputedRoutes) []*pbresource.Reference {
|
||||
var (
|
||||
out []*pbresource.Reference
|
||||
seen = make(map[resource.ReferenceKey]struct{})
|
||||
)
|
||||
for _, pc := range cr.Data.PortedConfigs {
|
||||
for _, target := range pc.Targets {
|
||||
ref := target.BackendRef.Ref
|
||||
rk := resource.NewReferenceKey(ref)
|
||||
if _, ok := seen[rk]; !ok {
|
||||
out = append(out, ref)
|
||||
seen[rk] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Cache: reverse SVC[*] => WI[*]
|
||||
func ServiceByWorkloadIdentityIndex() *index.Index {
|
||||
return indexers.RefOrIDIndex(
|
||||
"service-by-workload-identity",
|
||||
func(svc *types.DecodedService) []*pbresource.Reference {
|
||||
return GetWorkloadIdentitiesFromService(svc.Resource)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func GetWorkloadIdentitiesFromService(svc *pbresource.Resource) []*pbresource.Reference {
|
||||
ids := catalog.GetBoundIdentities(svc)
|
||||
|
||||
out := make([]*pbresource.Reference, 0, len(ids))
|
||||
for _, id := range ids {
|
||||
out = append(out, &pbresource.Reference{
|
||||
Type: pbauth.WorkloadIdentityType,
|
||||
Name: id,
|
||||
Tenancy: svc.Id.Tenancy,
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package meshindexes
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/internal/catalog"
|
||||
"github.com/hashicorp/consul/internal/mesh/internal/types"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
"github.com/hashicorp/consul/proto/private/prototest"
|
||||
)
|
||||
|
||||
func TestGetWorkloadIdentitiesFromService(t *testing.T) {
|
||||
tenancy := resource.DefaultNamespacedTenancy()
|
||||
|
||||
build := func(conds ...*pbresource.Condition) *pbresource.Resource {
|
||||
b := rtest.Resource(pbcatalog.ServiceType, "web").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, &pbcatalog.Service{})
|
||||
if len(conds) > 0 {
|
||||
b.WithStatus(catalog.EndpointsStatusKey, &pbresource.Status{
|
||||
Conditions: conds,
|
||||
})
|
||||
}
|
||||
return b.Build()
|
||||
}
|
||||
|
||||
fooRef := &pbresource.Reference{
|
||||
Type: pbauth.WorkloadIdentityType,
|
||||
Tenancy: tenancy,
|
||||
Name: "foo",
|
||||
}
|
||||
barRef := &pbresource.Reference{
|
||||
Type: pbauth.WorkloadIdentityType,
|
||||
Tenancy: tenancy,
|
||||
Name: "bar",
|
||||
}
|
||||
|
||||
makeRefs := func(refs ...*pbresource.Reference) []*pbresource.Reference {
|
||||
return refs
|
||||
}
|
||||
|
||||
run := GetWorkloadIdentitiesFromService
|
||||
|
||||
require.Empty(t, run(build(nil)))
|
||||
require.Empty(t, run(build(&pbresource.Condition{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: "",
|
||||
})))
|
||||
prototest.AssertDeepEqual(t, makeRefs(fooRef), run(build(&pbresource.Condition{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: "foo",
|
||||
})))
|
||||
require.Empty(t, run(build(&pbresource.Condition{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_FALSE,
|
||||
Message: "foo",
|
||||
})))
|
||||
prototest.AssertDeepEqual(t, makeRefs(barRef, fooRef), run(build(&pbresource.Condition{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: "bar,foo", // proper order
|
||||
})))
|
||||
prototest.AssertDeepEqual(t, makeRefs(barRef, fooRef), run(build(&pbresource.Condition{
|
||||
Type: catalog.StatusConditionBoundIdentities,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: "foo,bar", // incorrect order gets fixed
|
||||
})))
|
||||
}
|
||||
|
||||
func TestGetBackendServiceRefsFromComputedRoutes(t *testing.T) {
|
||||
type testcase struct {
|
||||
cr *types.DecodedComputedRoutes
|
||||
expect []*pbresource.Reference
|
||||
}
|
||||
|
||||
run := func(t *testing.T, tc testcase) {
|
||||
got := GetBackendServiceRefsFromComputedRoutes(tc.cr)
|
||||
prototest.AssertElementsMatch(t, tc.expect, got)
|
||||
}
|
||||
|
||||
tenancy := resource.DefaultNamespacedTenancy()
|
||||
|
||||
newRef := func(name string) *pbresource.Reference {
|
||||
return &pbresource.Reference{
|
||||
Type: pbcatalog.ServiceType,
|
||||
Tenancy: tenancy,
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
cr1 := resourcetest.Resource(pbmesh.ComputedRoutesType, "cr1").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, &pbmesh.ComputedRoutes{
|
||||
PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{
|
||||
"http": {
|
||||
Targets: map[string]*pbmesh.BackendTargetDetails{
|
||||
"opaque1": {
|
||||
BackendRef: &pbmesh.BackendReference{Ref: newRef("aaa")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}).
|
||||
Build()
|
||||
|
||||
cr2 := resourcetest.Resource(pbmesh.ComputedRoutesType, "cr2").
|
||||
WithTenancy(tenancy).
|
||||
WithData(t, &pbmesh.ComputedRoutes{
|
||||
PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{
|
||||
"http": {
|
||||
Targets: map[string]*pbmesh.BackendTargetDetails{
|
||||
"opaque1": {
|
||||
BackendRef: &pbmesh.BackendReference{Ref: newRef("aaa")},
|
||||
},
|
||||
"opaque2": {
|
||||
BackendRef: &pbmesh.BackendReference{Ref: newRef("bbb")},
|
||||
},
|
||||
},
|
||||
},
|
||||
"grpc": {
|
||||
Targets: map[string]*pbmesh.BackendTargetDetails{
|
||||
"opaque2": {
|
||||
BackendRef: &pbmesh.BackendReference{Ref: newRef("bbb")},
|
||||
},
|
||||
"opaque3": {
|
||||
BackendRef: &pbmesh.BackendReference{Ref: newRef("ccc")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}).
|
||||
Build()
|
||||
|
||||
cases := map[string]testcase{
|
||||
"one": {
|
||||
cr: resourcetest.MustDecode[*pbmesh.ComputedRoutes](t, cr1),
|
||||
expect: []*pbresource.Reference{
|
||||
newRef("aaa"),
|
||||
},
|
||||
},
|
||||
"two": {
|
||||
cr: resourcetest.MustDecode[*pbmesh.ComputedRoutes](t, cr2),
|
||||
expect: []*pbresource.Reference{
|
||||
newRef("aaa"),
|
||||
newRef("bbb"),
|
||||
newRef("ccc"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
run(t, tc)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -8,6 +8,8 @@ import (
|
|||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
)
|
||||
|
||||
type DecodedComputedExplicitDestinations = resource.DecodedResource[*pbmesh.ComputedExplicitDestinations]
|
||||
|
||||
func RegisterComputedExplicitDestinations(r resource.Registry) {
|
||||
r.Register(resource.Registration{
|
||||
Type: pbmesh.ComputedExplicitDestinationsType,
|
||||
|
|
|
@ -136,12 +136,6 @@ func validateComputedRoutes(res *DecodedComputedRoutes) error {
|
|||
Wrapped: fmt.Errorf("field should be empty"),
|
||||
}))
|
||||
}
|
||||
if target.ServiceEndpoints != nil {
|
||||
merr = multierror.Append(merr, wrapTargetErr(resource.ErrInvalidField{
|
||||
Name: "service_endpoints",
|
||||
Wrapped: fmt.Errorf("field should be empty"),
|
||||
}))
|
||||
}
|
||||
if len(target.IdentityRefs) > 0 {
|
||||
merr = multierror.Append(merr, wrapTargetErr(resource.ErrInvalidField{
|
||||
Name: "identity_refs",
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
||||
pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
|
@ -149,25 +148,6 @@ func TestValidateComputedRoutes(t *testing.T) {
|
|||
},
|
||||
expectErr: `invalid value of key "http" within ported_configs: invalid value of key "foo" within targets: invalid "service_endpoint_ref" field: field should be empty`,
|
||||
},
|
||||
"target/should not have service endpoints": {
|
||||
routes: &pbmesh.ComputedRoutes{
|
||||
PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{
|
||||
"http": {
|
||||
Config: &pbmesh.ComputedPortRoutes_Tcp{
|
||||
Tcp: &pbmesh.ComputedTCPRoute{},
|
||||
},
|
||||
Targets: map[string]*pbmesh.BackendTargetDetails{
|
||||
"foo": {
|
||||
Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT,
|
||||
MeshPort: "mesh",
|
||||
ServiceEndpoints: &pbcatalog.ServiceEndpoints{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectErr: `invalid value of key "http" within ported_configs: invalid value of key "foo" within targets: invalid "service_endpoints" field: field should be empty`,
|
||||
},
|
||||
"target/should not have identity refs": {
|
||||
routes: &pbmesh.ComputedRoutes{
|
||||
PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{
|
||||
|
|
|
@ -838,9 +838,6 @@ type BackendTargetDetails struct {
|
|||
DestinationConfig *DestinationConfig `protobuf:"bytes,5,opt,name=destination_config,json=destinationConfig,proto3" json:"destination_config,omitempty"`
|
||||
// ServiceEndpointsRef is not populated naturally and the field exists only for downstream consumers.
|
||||
ServiceEndpointsRef *pbproxystate.EndpointRef `protobuf:"bytes,24,opt,name=service_endpoints_ref,json=serviceEndpointsRef,proto3" json:"service_endpoints_ref,omitempty"`
|
||||
// ServiceEndpoints is not populated naturally and the field exists only for
|
||||
// downstream consumers.
|
||||
ServiceEndpoints *v2beta1.ServiceEndpoints `protobuf:"bytes,22,opt,name=service_endpoints,json=serviceEndpoints,proto3" json:"service_endpoints,omitempty"`
|
||||
// IdentityRefs are not populated naturally and the field exists only for
|
||||
// downstream consumers.
|
||||
IdentityRefs []*pbresource.Reference `protobuf:"bytes,23,rep,name=identity_refs,json=identityRefs,proto3" json:"identity_refs,omitempty"`
|
||||
|
@ -920,13 +917,6 @@ func (x *BackendTargetDetails) GetServiceEndpointsRef() *pbproxystate.EndpointRe
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *BackendTargetDetails) GetServiceEndpoints() *v2beta1.ServiceEndpoints {
|
||||
if x != nil {
|
||||
return x.ServiceEndpoints
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *BackendTargetDetails) GetIdentityRefs() []*pbresource.Reference {
|
||||
if x != nil {
|
||||
return x.IdentityRefs
|
||||
|
@ -1066,112 +1056,152 @@ var file_pbmesh_v2beta1_computed_routes_proto_rawDesc = []byte{
|
|||
0x72, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20,
|
||||
0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61,
|
||||
0x31, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x1a, 0x29, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65,
|
||||
0x74, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x64, 0x70,
|
||||
0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x70, 0x62, 0x6d,
|
||||
0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68,
|
||||
0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x1a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61,
|
||||
0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x1a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74,
|
||||
0x61, 0x31, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65,
|
||||
0x74, 0x61, 0x31, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x72,
|
||||
0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x28, 0x70, 0x62,
|
||||
0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x68, 0x74, 0x74,
|
||||
0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2c, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76,
|
||||
0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74,
|
||||
0x61, 0x74, 0x65, 0x2f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x1a, 0x19, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x72,
|
||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc7, 0x02,
|
||||
0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73,
|
||||
0x12, 0x67, 0x0a, 0x0e, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68,
|
||||
0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65,
|
||||
0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x4f, 0x0a, 0x10, 0x62, 0x6f, 0x75,
|
||||
0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e,
|
||||
0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0f, 0x62, 0x6f, 0x75, 0x6e, 0x64,
|
||||
0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0x73, 0x0a, 0x12, 0x50, 0x6f,
|
||||
0x72, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
|
||||
0x65, 0x79, 0x12, 0x47, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61,
|
||||
0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a,
|
||||
0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x87, 0x05, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x70,
|
||||
0x75, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x46,
|
||||
0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68,
|
||||
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
|
||||
0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d,
|
||||
0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x00,
|
||||
0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x46, 0x0a, 0x04, 0x67, 0x72, 0x70, 0x63, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62,
|
||||
0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x47, 0x52, 0x50,
|
||||
0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x00, 0x52, 0x04, 0x67, 0x72, 0x70, 0x63, 0x12, 0x43,
|
||||
0x0a, 0x03, 0x74, 0x63, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61,
|
||||
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d,
|
||||
0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70,
|
||||
0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x00, 0x52, 0x03,
|
||||
0x74, 0x63, 0x70, 0x12, 0x30, 0x0a, 0x14, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x66,
|
||||
0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x08, 0x52, 0x12, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4d, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f,
|
||||
0x72, 0x65, 0x66, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73,
|
||||
0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74,
|
||||
0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e,
|
||||
0x74, 0x52, 0x65, 0x66, 0x12, 0x46, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
|
||||
0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f,
|
||||
0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63,
|
||||
0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x58, 0x0a, 0x07,
|
||||
0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e,
|
||||
0x1a, 0x1b, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70,
|
||||
0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x64, 0x65,
|
||||
0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76,
|
||||
0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f,
|
||||
0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68,
|
||||
0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x1a, 0x28, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61,
|
||||
0x31, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d,
|
||||
0x65, 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2c, 0x70, 0x62, 0x6d,
|
||||
0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72,
|
||||
0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,
|
||||
0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x22, 0xc7, 0x02, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x52,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x67, 0x0a, 0x0e, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f,
|
||||
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e,
|
||||
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||
0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f,
|
||||
0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73,
|
||||
0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x74,
|
||||
0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x1a, 0x6f, 0x0a, 0x0c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x49, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
|
||||
0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e,
|
||||
0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54,
|
||||
0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x22, 0x65, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54,
|
||||
0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x4a, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18,
|
||||
0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x6f, 0x72,
|
||||
0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
|
||||
0x0d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x4f,
|
||||
0x0a, 0x10, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,
|
||||
0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0f,
|
||||
0x62, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a,
|
||||
0x73, 0x0a, 0x12, 0x50, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
|
||||
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x47, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
|
||||
0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76,
|
||||
0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x50,
|
||||
0x6f, 0x72, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x3a, 0x02, 0x38, 0x01, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x87, 0x05, 0x0a,
|
||||
0x12, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x73, 0x12, 0x46, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61,
|
||||
0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x48, 0x00, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x46, 0x0a, 0x04, 0x67,
|
||||
0x72, 0x70, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73,
|
||||
0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74,
|
||||
0x65, 0x64, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x00, 0x52, 0x04, 0x67,
|
||||
0x72, 0x70, 0x63, 0x12, 0x43, 0x0a, 0x03, 0x74, 0x63, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x48, 0x00, 0x52, 0x03, 0x74, 0x63, 0x70, 0x12, 0x30, 0x0a, 0x14, 0x75, 0x73, 0x69, 0x6e,
|
||||
0x67, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x66,
|
||||
0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4d, 0x0a, 0x0a, 0x70, 0x61,
|
||||
0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e,
|
||||
0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75,
|
||||
0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50,
|
||||
0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x09,
|
||||
0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x12, 0x46, 0x0a, 0x08, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x68, 0x61,
|
||||
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63,
|
||||
0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
|
||||
0x6c, 0x12, 0x58, 0x0a, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74,
|
||||
0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74,
|
||||
0x72, 0x79, 0x52, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x1a, 0x6f, 0x0a, 0x0c, 0x54,
|
||||
0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
|
||||
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x49, 0x0a,
|
||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68,
|
||||
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
|
||||
0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63,
|
||||
0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
|
||||
0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06,
|
||||
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x65, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74,
|
||||
0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x4a, 0x0a, 0x05, 0x72,
|
||||
0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73,
|
||||
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65,
|
||||
0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75,
|
||||
0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65,
|
||||
0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x9d, 0x03,
|
||||
0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x47, 0x0a, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68,
|
||||
0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68,
|
||||
0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73,
|
||||
0x12, 0x48, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61,
|
||||
0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65,
|
||||
0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x58, 0x0a, 0x0c, 0x62, 0x61,
|
||||
0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x42, 0x61, 0x63,
|
||||
0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
|
||||
0x52, 0x65, 0x66, 0x73, 0x12, 0x4c, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
|
||||
0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76,
|
||||
0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75,
|
||||
0x74, 0x73, 0x12, 0x49, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65,
|
||||
0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x74,
|
||||
0x72, 0x69, 0x65, 0x73, 0x52, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xa1, 0x01,
|
||||
0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x42, 0x61,
|
||||
0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b,
|
||||
0x65, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
|
||||
0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x48, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65,
|
||||
0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68,
|
||||
0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
|
||||
0x73, 0x22, 0x65, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x47, 0x52, 0x50,
|
||||
0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x4a, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18,
|
||||
0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
|
||||
0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32,
|
||||
0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54,
|
||||
0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c,
|
||||
0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x47, 0x52,
|
||||
0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c,
|
||||
0x65, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x9d, 0x03, 0x0a, 0x15, 0x43, 0x6f, 0x6d,
|
||||
0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75,
|
||||
0x70, 0x75, 0x74, 0x65, 0x64, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75,
|
||||
0x6c, 0x65, 0x12, 0x47, 0x0a, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65,
|
||||
0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x74,
|
||||
0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x74,
|
||||
0x63, 0x68, 0x52, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x48, 0x0a, 0x07, 0x66,
|
||||
0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68,
|
||||
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
|
||||
0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54,
|
||||
0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50,
|
||||
0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69,
|
||||
0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x58, 0x0a, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
|
||||
0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61,
|
||||
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d,
|
||||
0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70,
|
||||
0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52,
|
||||
0x75, 0x74, 0x65, 0x64, 0x47, 0x52, 0x50, 0x43, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52,
|
||||
0x65, 0x66, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x12,
|
||||
0x4c, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f,
|
||||
|
@ -1183,7 +1213,7 @@ var file_pbmesh_v2beta1_computed_routes_proto_rawDesc = []byte{
|
|||
0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48,
|
||||
0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52,
|
||||
0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xa1, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6d,
|
||||
0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
|
||||
0x70, 0x75, 0x74, 0x65, 0x64, 0x47, 0x52, 0x50, 0x43, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
|
||||
0x52, 0x65, 0x66, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x74,
|
||||
0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x61, 0x63,
|
||||
0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65,
|
||||
|
@ -1191,161 +1221,112 @@ var file_pbmesh_v2beta1_computed_routes_proto_rawDesc = []byte{
|
|||
0x68, 0x74, 0x12, 0x48, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65,
|
||||
0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c,
|
||||
0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x65, 0x0a, 0x11,
|
||||
0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x12, 0x4a, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x4a, 0x04, 0x08,
|
||||
0x01, 0x10, 0x02, 0x22, 0x9d, 0x03, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64,
|
||||
0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x47, 0x0a,
|
||||
0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d,
|
||||
0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75,
|
||||
0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47,
|
||||
0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x6d,
|
||||
0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x48, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
|
||||
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
|
||||
0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e,
|
||||
0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73,
|
||||
0x12, 0x58, 0x0a, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73,
|
||||
0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
|
||||
0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76,
|
||||
0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x47,
|
||||
0x52, 0x50, 0x43, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x52, 0x0b, 0x62,
|
||||
0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x12, 0x4c, 0x0a, 0x08, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68,
|
||||
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
|
||||
0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54,
|
||||
0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x52, 0x08,
|
||||
0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x72,
|
||||
0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68,
|
||||
0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c,
|
||||
0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x5d, 0x0a, 0x10,
|
||||
0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x12, 0x49, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73,
|
||||
0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e,
|
||||
0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x6f, 0x0a, 0x14, 0x43,
|
||||
0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52,
|
||||
0x75, 0x6c, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72,
|
||||
0x65, 0x66, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73,
|
||||
0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x07, 0x72, 0x65, 0x74, 0x72,
|
||||
0x69, 0x65, 0x73, 0x22, 0xa1, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64,
|
||||
0x47, 0x52, 0x50, 0x43, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x25,
|
||||
0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54,
|
||||
0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x48, 0x0a,
|
||||
0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e,
|
||||
0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75,
|
||||
0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47,
|
||||
0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07,
|
||||
0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x5d, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x70, 0x75,
|
||||
0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x49, 0x0a, 0x05, 0x72,
|
||||
0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73,
|
||||
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65,
|
||||
0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75,
|
||||
0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52,
|
||||
0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x6f, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74,
|
||||
0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x57,
|
||||
0x0a, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62,
|
||||
0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50,
|
||||
0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b,
|
||||
0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x22, 0x56, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x70, 0x75,
|
||||
0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66,
|
||||
0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x72, 0x67,
|
||||
0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e,
|
||||
0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68,
|
||||
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22,
|
||||
0xb2, 0x05, 0x0a, 0x14, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65,
|
||||
0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x4b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
|
||||
0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76,
|
||||
0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61,
|
||||
0x72, 0x67, 0x65, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52,
|
||||
0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x50, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
|
||||
0x5f, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73,
|
||||
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65,
|
||||
0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65,
|
||||
0x6e, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63,
|
||||
0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x73, 0x68, 0x5f,
|
||||
0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x68,
|
||||
0x50, 0x6f, 0x72, 0x74, 0x12, 0x5e, 0x0a, 0x0f, 0x66, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72,
|
||||
0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e,
|
||||
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||
0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f,
|
||||
0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x12, 0x5f, 0x0a, 0x12, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x52, 0x11, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x6b, 0x0a, 0x15, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x18,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
|
||||
0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62,
|
||||
0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74,
|
||||
0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x52, 0x13, 0x73,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52,
|
||||
0x65, 0x66, 0x12, 0x5f, 0x0a, 0x11, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x6e,
|
||||
0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e,
|
||||
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||
0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74,
|
||||
0x73, 0x52, 0x10, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69,
|
||||
0x6e, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f,
|
||||
0x72, 0x65, 0x66, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73,
|
||||
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,
|
||||
0x52, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x66, 0x73, 0x4a, 0x04,
|
||||
0x08, 0x06, 0x10, 0x15, 0x22, 0xfd, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65,
|
||||
0x64, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
||||
0x5e, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
|
||||
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
|
||||
0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74,
|
||||
0x65, 0x64, 0x54, 0x43, 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x52,
|
||||
0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x22, 0x56, 0x0a, 0x15,
|
||||
0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65,
|
||||
0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
|
||||
0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62,
|
||||
0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x77, 0x65,
|
||||
0x69, 0x67, 0x68, 0x74, 0x22, 0xd7, 0x04, 0x0a, 0x14, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
|
||||
0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x4b, 0x0a,
|
||||
0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x68, 0x61,
|
||||
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d,
|
||||
0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b,
|
||||
0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73,
|
||||
0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x50, 0x0a, 0x0b, 0x62, 0x61,
|
||||
0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73,
|
||||
0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e,
|
||||
0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,
|
||||
0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x1b, 0x0a, 0x09,
|
||||
0x6d, 0x65, 0x73, 0x68, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x08, 0x6d, 0x65, 0x73, 0x68, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x5e, 0x0a, 0x0f, 0x66, 0x61, 0x69,
|
||||
0x6c, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63,
|
||||
0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74,
|
||||
0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x6f,
|
||||
0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x6f,
|
||||
0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5f, 0x0a, 0x12, 0x64, 0x65, 0x73,
|
||||
0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
|
||||
0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32,
|
||||
0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x46, 0x61,
|
||||
0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12,
|
||||
0x42, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e,
|
||||
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||
0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d,
|
||||
0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a,
|
||||
0x0e, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47,
|
||||
0x72, 0x6f, 0x75, 0x70, 0x22, 0x44, 0x0a, 0x1b, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64,
|
||||
0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x74,
|
||||
0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x61, 0x63,
|
||||
0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2a, 0x99, 0x01, 0x0a, 0x18, 0x42,
|
||||
0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x65, 0x74, 0x61,
|
||||
0x69, 0x6c, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x27, 0x42, 0x41, 0x43, 0x4b, 0x45,
|
||||
0x4e, 0x44, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c,
|
||||
0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
|
||||
0x45, 0x44, 0x10, 0x00, 0x12, 0x26, 0x0a, 0x22, 0x42, 0x41, 0x43, 0x4b, 0x45, 0x4e, 0x44, 0x5f,
|
||||
0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x5f, 0x54,
|
||||
0x59, 0x50, 0x45, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x10, 0x01, 0x12, 0x28, 0x0a, 0x24,
|
||||
0x42, 0x41, 0x43, 0x4b, 0x45, 0x4e, 0x44, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x44,
|
||||
0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x44, 0x49,
|
||||
0x52, 0x45, 0x43, 0x54, 0x10, 0x02, 0x42, 0x94, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68,
|
||||
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
|
||||
0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x13, 0x43, 0x6f,
|
||||
0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
||||
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62,
|
||||
0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73,
|
||||
0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02,
|
||||
0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75,
|
||||
0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02,
|
||||
0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75,
|
||||
0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02,
|
||||
0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75,
|
||||
0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47,
|
||||
0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73,
|
||||
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a,
|
||||
0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x6b, 0x0a, 0x15, 0x73, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x5f,
|
||||
0x72, 0x65, 0x66, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73,
|
||||
0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78,
|
||||
0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52,
|
||||
0x65, 0x66, 0x52, 0x13, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f,
|
||||
0x69, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x66, 0x12, 0x49, 0x0a, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24,
|
||||
0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75,
|
||||
0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72,
|
||||
0x65, 0x6e, 0x63, 0x65, 0x52, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65,
|
||||
0x66, 0x73, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x16, 0x10, 0x17, 0x22, 0xfd,
|
||||
0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x6f,
|
||||
0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5e, 0x0a, 0x0c, 0x64, 0x65, 0x73,
|
||||
0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73,
|
||||
0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e,
|
||||
0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72,
|
||||
0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x64, 0x65, 0x73,
|
||||
0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x42, 0x0a, 0x04, 0x6d, 0x6f, 0x64,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
|
||||
0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c,
|
||||
0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f,
|
||||
0x76, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07,
|
||||
0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x61, 0x6d, 0x65, 0x6e,
|
||||
0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0d, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x44,
|
||||
0x0a, 0x1b, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76,
|
||||
0x65, 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a,
|
||||
0x0e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61,
|
||||
0x72, 0x67, 0x65, 0x74, 0x2a, 0x99, 0x01, 0x0a, 0x18, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
|
||||
0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x54, 0x79, 0x70,
|
||||
0x65, 0x12, 0x2b, 0x0a, 0x27, 0x42, 0x41, 0x43, 0x4b, 0x45, 0x4e, 0x44, 0x5f, 0x54, 0x41, 0x52,
|
||||
0x47, 0x45, 0x54, 0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45,
|
||||
0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x26,
|
||||
0x0a, 0x22, 0x42, 0x41, 0x43, 0x4b, 0x45, 0x4e, 0x44, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54,
|
||||
0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x49,
|
||||
0x52, 0x45, 0x43, 0x54, 0x10, 0x01, 0x12, 0x28, 0x0a, 0x24, 0x42, 0x41, 0x43, 0x4b, 0x45, 0x4e,
|
||||
0x44, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53,
|
||||
0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x10, 0x02,
|
||||
0x42, 0x94, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
|
||||
0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76,
|
||||
0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x13, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64,
|
||||
0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67,
|
||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
|
||||
0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76,
|
||||
0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74,
|
||||
0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68,
|
||||
0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68,
|
||||
0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69,
|
||||
0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68,
|
||||
0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
|
||||
0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a,
|
||||
0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -1392,8 +1373,7 @@ var file_pbmesh_v2beta1_computed_routes_proto_goTypes = []interface{}{
|
|||
(*BackendReference)(nil), // 26: hashicorp.consul.mesh.v2beta1.BackendReference
|
||||
(*DestinationConfig)(nil), // 27: hashicorp.consul.mesh.v2beta1.DestinationConfig
|
||||
(*pbproxystate.EndpointRef)(nil), // 28: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointRef
|
||||
(*v2beta1.ServiceEndpoints)(nil), // 29: hashicorp.consul.catalog.v2beta1.ServiceEndpoints
|
||||
(v2beta1.FailoverMode)(0), // 30: hashicorp.consul.catalog.v2beta1.FailoverMode
|
||||
(v2beta1.FailoverMode)(0), // 29: hashicorp.consul.catalog.v2beta1.FailoverMode
|
||||
}
|
||||
var file_pbmesh_v2beta1_computed_routes_proto_depIdxs = []int32{
|
||||
15, // 0: hashicorp.consul.mesh.v2beta1.ComputedRoutes.ported_configs:type_name -> hashicorp.consul.mesh.v2beta1.ComputedRoutes.PortedConfigsEntry
|
||||
|
@ -1425,17 +1405,16 @@ var file_pbmesh_v2beta1_computed_routes_proto_depIdxs = []int32{
|
|||
13, // 26: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.failover_config:type_name -> hashicorp.consul.mesh.v2beta1.ComputedFailoverConfig
|
||||
27, // 27: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.destination_config:type_name -> hashicorp.consul.mesh.v2beta1.DestinationConfig
|
||||
28, // 28: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.service_endpoints_ref:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointRef
|
||||
29, // 29: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.service_endpoints:type_name -> hashicorp.consul.catalog.v2beta1.ServiceEndpoints
|
||||
17, // 30: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.identity_refs:type_name -> hashicorp.consul.resource.Reference
|
||||
14, // 31: hashicorp.consul.mesh.v2beta1.ComputedFailoverConfig.destinations:type_name -> hashicorp.consul.mesh.v2beta1.ComputedFailoverDestination
|
||||
30, // 32: hashicorp.consul.mesh.v2beta1.ComputedFailoverConfig.mode:type_name -> hashicorp.consul.catalog.v2beta1.FailoverMode
|
||||
2, // 33: hashicorp.consul.mesh.v2beta1.ComputedRoutes.PortedConfigsEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.ComputedPortRoutes
|
||||
12, // 34: hashicorp.consul.mesh.v2beta1.ComputedPortRoutes.TargetsEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.BackendTargetDetails
|
||||
35, // [35:35] is the sub-list for method output_type
|
||||
35, // [35:35] is the sub-list for method input_type
|
||||
35, // [35:35] is the sub-list for extension type_name
|
||||
35, // [35:35] is the sub-list for extension extendee
|
||||
0, // [0:35] is the sub-list for field type_name
|
||||
17, // 29: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.identity_refs:type_name -> hashicorp.consul.resource.Reference
|
||||
14, // 30: hashicorp.consul.mesh.v2beta1.ComputedFailoverConfig.destinations:type_name -> hashicorp.consul.mesh.v2beta1.ComputedFailoverDestination
|
||||
29, // 31: hashicorp.consul.mesh.v2beta1.ComputedFailoverConfig.mode:type_name -> hashicorp.consul.catalog.v2beta1.FailoverMode
|
||||
2, // 32: hashicorp.consul.mesh.v2beta1.ComputedRoutes.PortedConfigsEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.ComputedPortRoutes
|
||||
12, // 33: hashicorp.consul.mesh.v2beta1.ComputedPortRoutes.TargetsEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.BackendTargetDetails
|
||||
34, // [34:34] is the sub-list for method output_type
|
||||
34, // [34:34] is the sub-list for method input_type
|
||||
34, // [34:34] is the sub-list for extension type_name
|
||||
34, // [34:34] is the sub-list for extension extendee
|
||||
0, // [0:34] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_pbmesh_v2beta1_computed_routes_proto_init() }
|
||||
|
|
|
@ -7,7 +7,6 @@ package hashicorp.consul.mesh.v2beta1;
|
|||
|
||||
import "pbcatalog/v2beta1/failover_policy.proto";
|
||||
import "pbcatalog/v2beta1/protocol.proto";
|
||||
import "pbcatalog/v2beta1/service_endpoints.proto";
|
||||
import "pbmesh/v2beta1/common.proto";
|
||||
import "pbmesh/v2beta1/destination_policy.proto";
|
||||
import "pbmesh/v2beta1/grpc_route.proto";
|
||||
|
@ -139,9 +138,7 @@ message BackendTargetDetails {
|
|||
// ServiceEndpointsRef is not populated naturally and the field exists only for downstream consumers.
|
||||
pbproxystate.EndpointRef service_endpoints_ref = 24;
|
||||
|
||||
// ServiceEndpoints is not populated naturally and the field exists only for
|
||||
// downstream consumers.
|
||||
hashicorp.consul.catalog.v2beta1.ServiceEndpoints service_endpoints = 22;
|
||||
reserved 22; // formerly ServiceEndpoints, never marshaled
|
||||
|
||||
// IdentityRefs are not populated naturally and the field exists only for
|
||||
// downstream consumers.
|
||||
|
|
Loading…
Reference in New Issue