Skip to content

Commit

Permalink
bugfix: filter repeated resources.
Browse files Browse the repository at this point in the history
Signed-off-by: qicz <[email protected]>
  • Loading branch information
qicz committed Oct 19, 2024
1 parent 70c568b commit 55d5a5a
Show file tree
Hide file tree
Showing 11 changed files with 540 additions and 161 deletions.
9 changes: 7 additions & 2 deletions internal/cmd/egctl/translate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"

"github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/utils/field"
"github.com/envoyproxy/gateway/internal/utils/file"
)
Expand Down Expand Up @@ -362,8 +363,12 @@ func TestTranslate(t *testing.T) {
// want.GatewayClass.Status.SupportedFeatures = status.GatewaySupportedFeatures
// }

opts := cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime")
require.Empty(t, cmp.Diff(want, got, opts))
opts := []cmp.Option{
cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"),
cmpopts.IgnoreFields(resource.Resources{}, "Cache"),
cmpopts.EquateEmpty(),
}
require.Empty(t, cmp.Diff(want, got, opts...))
})
}
}
Expand Down
16 changes: 8 additions & 8 deletions internal/gatewayapi/resource/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func loadKubernetesYAMLToResources(input []byte, addMissingResources bool) (*Res
},
Spec: typedSpec.(gwapiv1.GatewaySpec),
}
resources.Gateways = append(resources.Gateways, gateway)
resources.AppendResource(gateway)

Check warning on line 144 in internal/gatewayapi/resource/load.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/resource/load.go#L144

Added line #L144 was not covered by tests
case KindTCPRoute:
typedSpec := spec.Interface()
tcpRoute := &gwapiv1a2.TCPRoute{
Expand Down Expand Up @@ -213,7 +213,7 @@ func loadKubernetesYAMLToResources(input []byte, addMissingResources bool) (*Res
Name: name,
},
}
resources.Namespaces = append(resources.Namespaces, namespace)
resources.AppendResource(namespace)

Check warning on line 216 in internal/gatewayapi/resource/load.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/resource/load.go#L216

Added line #L216 was not covered by tests
providedNamespaceMap.Insert(name)
case KindService:
typedSpec := spec.Interface()
Expand Down Expand Up @@ -241,7 +241,7 @@ func loadKubernetesYAMLToResources(input []byte, addMissingResources bool) (*Res
},
Spec: typedSpec.(egv1a1.EnvoyPatchPolicySpec),
}
resources.EnvoyPatchPolicies = append(resources.EnvoyPatchPolicies, envoyPatchPolicy)
resources.AppendResource(envoyPatchPolicy)

Check warning on line 244 in internal/gatewayapi/resource/load.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/resource/load.go#L244

Added line #L244 was not covered by tests
case KindClientTrafficPolicy:
typedSpec := spec.Interface()
clientTrafficPolicy := &egv1a1.ClientTrafficPolicy{
Expand All @@ -254,7 +254,7 @@ func loadKubernetesYAMLToResources(input []byte, addMissingResources bool) (*Res
},
Spec: typedSpec.(egv1a1.ClientTrafficPolicySpec),
}
resources.ClientTrafficPolicies = append(resources.ClientTrafficPolicies, clientTrafficPolicy)
resources.AppendResource(clientTrafficPolicy)

Check warning on line 257 in internal/gatewayapi/resource/load.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/resource/load.go#L257

Added line #L257 was not covered by tests
case KindBackendTrafficPolicy:
typedSpec := spec.Interface()
backendTrafficPolicy := &egv1a1.BackendTrafficPolicy{
Expand All @@ -267,7 +267,7 @@ func loadKubernetesYAMLToResources(input []byte, addMissingResources bool) (*Res
},
Spec: typedSpec.(egv1a1.BackendTrafficPolicySpec),
}
resources.BackendTrafficPolicies = append(resources.BackendTrafficPolicies, backendTrafficPolicy)
resources.AppendResource(backendTrafficPolicy)

Check warning on line 270 in internal/gatewayapi/resource/load.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/resource/load.go#L270

Added line #L270 was not covered by tests
case KindSecurityPolicy:
typedSpec := spec.Interface()
securityPolicy := &egv1a1.SecurityPolicy{
Expand All @@ -294,7 +294,7 @@ func loadKubernetesYAMLToResources(input []byte, addMissingResources bool) (*Res
},
Spec: typedSpec.(egv1a1.HTTPRouteFilterSpec),
}
resources.HTTPRouteFilters = append(resources.HTTPRouteFilters, httpRouteFilter)
resources.AppendResource(httpRouteFilter)

Check warning on line 297 in internal/gatewayapi/resource/load.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/resource/load.go#L297

Added line #L297 was not covered by tests
}

return nil
Expand All @@ -309,7 +309,7 @@ func loadKubernetesYAMLToResources(input []byte, addMissingResources bool) (*Res
Name: config.DefaultNamespace,
},
}
resources.Namespaces = append(resources.Namespaces, namespace)
resources.AppendResource(namespace)

Check warning on line 312 in internal/gatewayapi/resource/load.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/resource/load.go#L312

Added line #L312 was not covered by tests
providedNamespaceMap.Insert(config.DefaultNamespace)
}
}
Expand All @@ -322,7 +322,7 @@ func loadKubernetesYAMLToResources(input []byte, addMissingResources bool) (*Res
Name: ns,
},
}
resources.Namespaces = append(resources.Namespaces, namespace)
resources.AppendResource(namespace)

Check warning on line 325 in internal/gatewayapi/resource/load.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/resource/load.go#L325

Added line #L325 was not covered by tests
}
}

Expand Down
95 changes: 5 additions & 90 deletions internal/gatewayapi/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ package resource

import (
"cmp"
"reflect"

gcmp "github.com/google/go-cmp/cmp"
gcmpopt "github.com/google/go-cmp/cmp/cmpopts"
"golang.org/x/exp/slices"
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
Expand Down Expand Up @@ -64,6 +65,7 @@ type Resources struct {
ExtensionServerPolicies []unstructured.Unstructured `json:"extensionServerPolicies,omitempty" yaml:"extensionServerPolicies,omitempty"`
Backends []*egv1a1.Backend `json:"backends,omitempty" yaml:"backends,omitempty"`
HTTPRouteFilters []*egv1a1.HTTPRouteFilter `json:"httpFilters,omitempty" yaml:"httpFilters,omitempty"`
Cache *Cache `json:"-" yaml:"-"`
}

func NewResources() *Resources {
Expand All @@ -88,97 +90,10 @@ func NewResources() *Resources {
ExtensionServerPolicies: []unstructured.Unstructured{},
Backends: []*egv1a1.Backend{},
HTTPRouteFilters: []*egv1a1.HTTPRouteFilter{},
Cache: newCache(),
}
}

func (r *Resources) GetNamespace(name string) *corev1.Namespace {
for _, ns := range r.Namespaces {
if ns.Name == name {
return ns
}
}

return nil
}

func (r *Resources) GetEnvoyProxy(namespace, name string) *egv1a1.EnvoyProxy {
for _, ep := range r.EnvoyProxiesForGateways {
if ep.Namespace == namespace && ep.Name == name {
return ep
}
}

return nil
}

func (r *Resources) GetService(namespace, name string) *corev1.Service {
for _, svc := range r.Services {
if svc.Namespace == namespace && svc.Name == name {
return svc
}
}

return nil
}

func (r *Resources) GetServiceImport(namespace, name string) *mcsapiv1a1.ServiceImport {
for _, svcImp := range r.ServiceImports {
if svcImp.Namespace == namespace && svcImp.Name == name {
return svcImp
}
}

return nil
}

func (r *Resources) GetBackend(namespace, name string) *egv1a1.Backend {
for _, be := range r.Backends {
if be.Namespace == namespace && be.Name == name {
return be
}
}

return nil
}

func (r *Resources) GetSecret(namespace, name string) *corev1.Secret {
for _, secret := range r.Secrets {
if secret.Namespace == namespace && secret.Name == name {
return secret
}
}

return nil
}

func (r *Resources) GetConfigMap(namespace, name string) *corev1.ConfigMap {
for _, configMap := range r.ConfigMaps {
if configMap.Namespace == namespace && configMap.Name == name {
return configMap
}
}

return nil
}

func (r *Resources) GetEndpointSlicesForBackend(svcNamespace, svcName string, backendKind string) []*discoveryv1.EndpointSlice {
var endpointSlices []*discoveryv1.EndpointSlice
for _, endpointSlice := range r.EndpointSlices {
var backendSelectorLabel string
switch backendKind {
case KindService:
backendSelectorLabel = discoveryv1.LabelServiceName
case KindServiceImport:
backendSelectorLabel = mcsapiv1a1.LabelServiceName
}
if svcNamespace == endpointSlice.Namespace &&
endpointSlice.GetLabels()[backendSelectorLabel] == svcName {
endpointSlices = append(endpointSlices, endpointSlice)
}
}
return endpointSlices
}

// ControllerResources holds all the GatewayAPI resources per GatewayClass
type ControllerResources []*Resources

Expand All @@ -200,7 +115,7 @@ func (c *ControllerResources) Equal(y *ControllerResources) bool {
c.sort()
y = y.DeepCopy()
y.sort()
return reflect.DeepEqual(c, y)
return gcmp.Equal(*c, *y, gcmpopt.IgnoreFields(Resources{}, "Cache"))
}

func (c *ControllerResources) sort() {
Expand Down
66 changes: 66 additions & 0 deletions internal/gatewayapi/resource/resource_cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright Envoy Gateway Authors
// SPDX-License-Identifier: Apache-2.0
// The full text of the Apache license is available in the LICENSE file at
// the root of the repo.

package resource

var cacheKinds = []string{
"Gateway", "ReferenceGrant", "Namespace",
"ServiceImport", "EndpointSlice",
"Secret", "ConfigMap", "EnvoyPatchPolicy",
"ClientTrafficPolicy", "BackendTrafficPolicy", "SecurityPolicy",
"BackendTLSPolicy", "EnvoyExtensionPolicy", "HTTPRouteFilter",
}

// Set holds the resources with the kind.
// +k8s:deepcopy-gen=true
type Set struct {
Values map[string]string `json:"-" yaml:"-"`
}

func newSet() *Set {
return &Set{
Values: map[string]string{},
}
}

func (s *Set) Has(item string) bool {
_, contained := s.Values[item]
return contained
}

func (s *Set) Insert(items ...string) {
for _, item := range items {
s.Values[item] = ""
}
}

// Cache holds some duplicate resources in memory.
// +k8s:deepcopy-gen=true
type Cache struct {
ResourceSet map[string]*Set `json:"-" yaml:"-"`
}

func (r *Resources) InitCache() {
r.Cache = newCache()

Check warning on line 46 in internal/gatewayapi/resource/resource_cache.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/resource/resource_cache.go#L45-L46

Added lines #L45 - L46 were not covered by tests
}

func newCache() *Cache {
resourceSets := make(map[string]*Set, len(cacheKinds))
for _, kind := range cacheKinds {
resourceSets[kind] = newSet()
}

return &Cache{
ResourceSet: resourceSets,
}
}

func (r *Resources) resourceCache(kind string) *Set {
if rs, ok := r.Cache.ResourceSet[kind]; ok {
return rs
}

return newSet()

Check warning on line 65 in internal/gatewayapi/resource/resource_cache.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/resource/resource_cache.go#L65

Added line #L65 was not covered by tests
}
Loading

0 comments on commit 55d5a5a

Please sign in to comment.