diff --git a/pkg/core/xds/resource.go b/pkg/core/xds/resource.go index c79be9cdf22a..836738058a82 100644 --- a/pkg/core/xds/resource.go +++ b/pkg/core/xds/resource.go @@ -1,6 +1,7 @@ package xds import ( + "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" @@ -35,3 +36,50 @@ func (rs ResourceList) ToDeltaDiscoveryResponse() *envoy.DeltaDiscoveryResponse } return resp } + +// ResourceSet represents a set of generic xDS resources. +type ResourceSet struct { + // we want to keep resources in the order they were added + resources []*Resource + // we want to prevent duplicates + typeToNamesIndex map[string]map[string]bool +} + +func (s *ResourceSet) Contains(name string, resource ResourcePayload) bool { + names, ok := s.typeToNamesIndex[s.typeName(resource)] + if !ok { + return false + } + _, ok = names[name] + return ok +} + +func (s *ResourceSet) Add(resources ...*Resource) *ResourceSet { + for _, resource := range resources { + if s.Contains(resource.Name, resource.Resource) { + continue + } + s.resources = append(s.resources, resource) + s.index(resource) + } + return s +} + +func (s *ResourceSet) typeName(resource ResourcePayload) string { + return proto.MessageName(resource) +} + +func (s *ResourceSet) index(resource *Resource) { + if s.typeToNamesIndex == nil { + s.typeToNamesIndex = map[string]map[string]bool{} + } + typeName := s.typeName(resource.Resource) + if s.typeToNamesIndex[typeName] == nil { + s.typeToNamesIndex[typeName] = map[string]bool{} + } + s.typeToNamesIndex[typeName][resource.Name] = true +} + +func (s *ResourceSet) List() []*Resource { + return s.resources +} diff --git a/pkg/xds/generator/resource_generator_test.go b/pkg/core/xds/resource_test.go similarity index 85% rename from pkg/xds/generator/resource_generator_test.go rename to pkg/core/xds/resource_test.go index 640724fac100..ca8268e6a4db 100644 --- a/pkg/xds/generator/resource_generator_test.go +++ b/pkg/core/xds/resource_test.go @@ -1,12 +1,10 @@ -package generator_test +package xds_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - . "github.com/Kong/kuma/pkg/xds/generator" - - core_xds "github.com/Kong/kuma/pkg/core/xds" + . "github.com/Kong/kuma/pkg/core/xds" envoy "github.com/envoyproxy/go-control-plane/envoy/api/v2" ) @@ -22,7 +20,7 @@ var _ = Describe("ResourceSet", func() { It("set of 1 element should return a list of 1 element", func() { // given - resource := &core_xds.Resource{ + resource := &Resource{ Name: "backend", Version: "v1", Resource: &envoy.Cluster{ @@ -40,14 +38,14 @@ var _ = Describe("ResourceSet", func() { It("set of 2 elements should return a list of 2 elements", func() { // given - resource1 := &core_xds.Resource{ + resource1 := &Resource{ Name: "backend", Version: "v1", Resource: &envoy.Cluster{ Name: "backend", }, } - resource2 := &core_xds.Resource{ + resource2 := &Resource{ Name: "outbound:127.0.0.1:8080", Version: "v2", Resource: &envoy.Listener{ @@ -68,14 +66,14 @@ var _ = Describe("ResourceSet", func() { It("should not be possible to add 2 resources with same name and type", func() { // given - resource1 := &core_xds.Resource{ + resource1 := &Resource{ Name: "backend", Version: "v1", Resource: &envoy.Cluster{ Name: "backend", }, } - resource2 := &core_xds.Resource{ + resource2 := &Resource{ Name: "backend", Version: "v2", Resource: &envoy.Cluster{ @@ -96,14 +94,14 @@ var _ = Describe("ResourceSet", func() { It("should be possible to add 2 resources with same name but different types", func() { // given - resource1 := &core_xds.Resource{ + resource1 := &Resource{ Name: "backend", Version: "v1", Resource: &envoy.Cluster{ Name: "backend", }, } - resource2 := &core_xds.Resource{ + resource2 := &Resource{ Name: "backend", Version: "v2", Resource: &envoy.Listener{ diff --git a/pkg/xds/generator/proxy_template.go b/pkg/xds/generator/proxy_template.go index d7f120be4c2f..c03a1b847553 100644 --- a/pkg/xds/generator/proxy_template.go +++ b/pkg/xds/generator/proxy_template.go @@ -94,7 +94,7 @@ func (_ InboundProxyGenerator) Generate(ctx xds_context.Context, proxy *model.Pr return nil, nil } virtual := proxy.Dataplane.Spec.Networking.GetTransparentProxying().GetRedirectPort() != 0 - resources := &ResourceSet{} + resources := &model.ResourceSet{} for _, endpoint := range endpoints { // generate CDS resource localClusterName := localClusterName(endpoint.WorkloadPort) @@ -124,7 +124,7 @@ func (g OutboundProxyGenerator) Generate(ctx xds_context.Context, proxy *model.P return nil, nil } virtual := proxy.Dataplane.Spec.Networking.GetTransparentProxying().GetRedirectPort() != 0 - resources := &ResourceSet{} + resources := &model.ResourceSet{} sourceService := proxy.Dataplane.Spec.GetIdentifyingService() for i, oface := range ofaces { endpoint, err := kuma_mesh.ParseOutboundInterface(oface.Interface) diff --git a/pkg/xds/generator/resource_generator.go b/pkg/xds/generator/resource_generator.go index 6838c26682ea..419abb20f15a 100644 --- a/pkg/xds/generator/resource_generator.go +++ b/pkg/xds/generator/resource_generator.go @@ -1,8 +1,6 @@ package generator import ( - "github.com/golang/protobuf/proto" - model "github.com/Kong/kuma/pkg/core/xds" xds_context "github.com/Kong/kuma/pkg/xds/context" ) @@ -24,49 +22,3 @@ func (c CompositeResourceGenerator) Generate(ctx xds_context.Context, proxy *mod } return resources, nil } - -type ResourceSet struct { - // we want to keep resources in the order they were added - resources []*model.Resource - // we want to prevent duplicates - typeToNamesIndex map[string]map[string]bool -} - -func (s *ResourceSet) Contains(name string, resource model.ResourcePayload) bool { - names, ok := s.typeToNamesIndex[s.typeName(resource)] - if !ok { - return false - } - _, ok = names[name] - return ok -} - -func (s *ResourceSet) Add(resources ...*model.Resource) *ResourceSet { - for _, resource := range resources { - if s.Contains(resource.Name, resource.Resource) { - continue - } - s.resources = append(s.resources, resource) - s.index(resource) - } - return s -} - -func (s *ResourceSet) typeName(resource model.ResourcePayload) string { - return proto.MessageName(resource) -} - -func (s *ResourceSet) index(resource *model.Resource) { - if s.typeToNamesIndex == nil { - s.typeToNamesIndex = map[string]map[string]bool{} - } - typeName := s.typeName(resource.Resource) - if s.typeToNamesIndex[typeName] == nil { - s.typeToNamesIndex[typeName] = map[string]bool{} - } - s.typeToNamesIndex[typeName][resource.Name] = true -} - -func (s *ResourceSet) List() []*model.Resource { - return s.resources -}