This is an automated email from the ASF dual-hosted git repository.
bzp2010 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git
The following commit(s) were added to refs/heads/master by this push:
new 3f7475e4 feat(cache): rewrite global_rules and plugin_metadata as
owned rows (#2884)
3f7475e4 is described below
commit 3f7475e4bdb9a8a777fa5d4d7b95d029250b9468
Author: Zeping Bai <[email protected]>
AuthorDate: Fri Sep 18 18:27:00 2026 +0800
feat(cache): rewrite global_rules and plugin_metadata as owned rows (#2884)
---
api/adc/types.go | 7 -
api/adc/zz_generated.deepcopy.go | 17 --
internal/adc/cache/cache.go | 61 +++++-
internal/adc/cache/indexer.go | 24 +++
internal/adc/cache/memdb.go | 54 +++++-
internal/adc/cache/noop_db.go | 24 ++-
internal/adc/cache/schema.go | 19 +-
internal/adc/cache/store.go | 332 +++++++++++++++++---------------
internal/adc/cache/store_test.go | 85 +++++++-
internal/provider/apisix/status.go | 17 +-
internal/provider/apisix/status_test.go | 38 ++--
11 files changed, 438 insertions(+), 240 deletions(-)
diff --git a/api/adc/types.go b/api/adc/types.go
index cbda8c66..475ff1a6 100644
--- a/api/adc/types.go
+++ b/api/adc/types.go
@@ -92,13 +92,6 @@ func (g *GlobalRule) DeepCopy() GlobalRule {
return GlobalRule(copied)
}
-// +k8s:deepcopy-gen=true
-type GlobalRuleItem struct {
- Metadata `json:",inline" yaml:",inline"`
-
- Plugins Plugins `json:"plugins" yaml:"plugins"`
-}
-
type PluginMetadata Plugins
func (p *PluginMetadata) DeepCopy() PluginMetadata {
diff --git a/api/adc/zz_generated.deepcopy.go b/api/adc/zz_generated.deepcopy.go
index 90ce2f81..b117ad34 100644
--- a/api/adc/zz_generated.deepcopy.go
+++ b/api/adc/zz_generated.deepcopy.go
@@ -246,23 +246,6 @@ func (in *ForwardAuthConfig) DeepCopy() *ForwardAuthConfig
{
return out
}
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
-func (in *GlobalRuleItem) DeepCopyInto(out *GlobalRuleItem) {
- *out = *in
- in.Metadata.DeepCopyInto(&out.Metadata)
- out.Plugins = in.Plugins.DeepCopy()
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver,
creating a new GlobalRuleItem.
-func (in *GlobalRuleItem) DeepCopy() *GlobalRuleItem {
- if in == nil {
- return nil
- }
- out := new(GlobalRuleItem)
- in.DeepCopyInto(out)
- return out
-}
-
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver,
writing into out. in must be non-nil.
func (in *HMACAuthConsumerConfig) DeepCopyInto(out *HMACAuthConsumerConfig) {
*out = *in
diff --git a/internal/adc/cache/cache.go b/internal/adc/cache/cache.go
index db3f6cb9..198e301b 100644
--- a/internal/adc/cache/cache.go
+++ b/internal/adc/cache/cache.go
@@ -19,8 +19,40 @@ package cache
import (
types "github.com/apache/apisix-ingress-controller/api/adc"
+ internaltypes
"github.com/apache/apisix-ingress-controller/internal/types"
)
+// GlobalRuleRow is one global_rules plugin, keyed by the plugin name. Owner
is the
+// Kubernetes resource that declared it: a GatewayProxy or an ApisixGlobalRule.
+type GlobalRuleRow struct {
+ ID string
+ Owner internaltypes.NamespacedNameKind
+ Config any
+}
+
+func (r *GlobalRuleRow) DeepCopy() *GlobalRuleRow {
+ out := *r
+ out.Config = copyPluginConfig(r.ID, r.Config)
+ return &out
+}
+
+// PluginMetadataRow is one plugin_metadata entry, keyed by the plugin name.
It needs no
+// owner: its only source is the GatewayProxy the cacheKey itself names.
+type PluginMetadataRow struct {
+ ID string
+ Config any
+}
+
+func (r *PluginMetadataRow) DeepCopy() *PluginMetadataRow {
+ out := *r
+ out.Config = copyPluginConfig(r.ID, r.Config)
+ return &out
+}
+
+func copyPluginConfig(name string, config any) any {
+ return types.Plugins{name: config}.DeepCopy()[name]
+}
+
type Cache interface {
Insert(obj any) error
Delete(obj any) error
@@ -32,7 +64,9 @@ type Cache interface {
// InsertConsumer adds or updates consumer to cache.
InsertConsumer(*types.Consumer) error
// InsertGlobalRule adds or updates global rule to cache.
- InsertGlobalRule(*types.GlobalRuleItem) error
+ InsertGlobalRule(*GlobalRuleRow) error
+ // InsertPluginMetadata adds or updates plugin metadata to cache.
+ InsertPluginMetadata(*PluginMetadataRow) error
// GetSSL finds the ssl from cache according to the primary index (id).
GetSSL(string) (*types.SSL, error)
@@ -41,7 +75,9 @@ type Cache interface {
// GetConsumer finds the consumer from cache according to the primary
index (username).
GetConsumer(string) (*types.Consumer, error)
// GetGlobalRule finds the global rule from cache according to the
primary index (id).
- GetGlobalRule(string) (*types.GlobalRuleItem, error)
+ GetGlobalRule(string) (*GlobalRuleRow, error)
+ // GetPluginMetadata finds the plugin metadata from cache according to
the primary index (id).
+ GetPluginMetadata(string) (*PluginMetadataRow, error)
// DeleteSSL deletes the specified ssl in cache.
DeleteSSL(*types.SSL) error
@@ -50,7 +86,9 @@ type Cache interface {
// DeleteConsumer deletes the specified consumer in cache.
DeleteConsumer(*types.Consumer) error
// DeleteGlobalRule deletes the specified global rule in cache.
- DeleteGlobalRule(*types.GlobalRuleItem) error
+ DeleteGlobalRule(*GlobalRuleRow) error
+ // DeletePluginMetadata deletes the specified plugin metadata in cache.
+ DeletePluginMetadata(*PluginMetadataRow) error
// ListSSL lists all ssl objects in cache.
ListSSL(...ListOption) ([]*types.SSL, error)
@@ -59,7 +97,9 @@ type Cache interface {
// ListConsumers lists all consumer objects in cache.
ListConsumers(...ListOption) ([]*types.Consumer, error)
// ListGlobalRules lists all global rule objects in cache.
- ListGlobalRules(...ListOption) ([]*types.GlobalRuleItem, error)
+ ListGlobalRules(...ListOption) ([]*GlobalRuleRow, error)
+ // ListPluginMetadata lists all plugin metadata objects in cache.
+ ListPluginMetadata(...ListOption) ([]*PluginMetadataRow, error)
}
type ListOption interface {
@@ -68,12 +108,16 @@ type ListOption interface {
type ListOptions struct {
KindLabelSelector *KindLabelSelector
+ OwnerSelector *OwnerSelector
}
func (o *ListOptions) ApplyToList(lo *ListOptions) {
if o.KindLabelSelector != nil {
lo.KindLabelSelector = o.KindLabelSelector
}
+ if o.OwnerSelector != nil {
+ lo.OwnerSelector = o.OwnerSelector
+ }
}
func (o *ListOptions) ApplyOptions(opts []ListOption) *ListOptions {
@@ -92,3 +136,12 @@ type KindLabelSelector struct {
func (o *KindLabelSelector) ApplyToList(opts *ListOptions) {
opts.KindLabelSelector = o
}
+
+// OwnerSelector lists only the global rules declared by Owner.
+type OwnerSelector struct {
+ Owner internaltypes.NamespacedNameKind
+}
+
+func (o *OwnerSelector) ApplyToList(opts *ListOptions) {
+ opts.OwnerSelector = o
+}
diff --git a/internal/adc/cache/indexer.go b/internal/adc/cache/indexer.go
index ad9dda3b..d9dc62c5 100644
--- a/internal/adc/cache/indexer.go
+++ b/internal/adc/cache/indexer.go
@@ -23,10 +23,12 @@ import (
"github.com/apache/apisix-ingress-controller/api/adc"
"github.com/apache/apisix-ingress-controller/internal/controller/label"
+ "github.com/apache/apisix-ingress-controller/internal/types"
)
const (
KindLabelIndex = "label"
+ OwnerIndex = "owner"
)
/*
@@ -94,3 +96,25 @@ func (emi *LabelIndexer) FromArgs(args ...any) ([]byte,
error) {
return emi.genKey(labelValues), nil
}
+
+// ownerIndexer indexes a GlobalRuleRow by its Owner.
+type ownerIndexer struct{}
+
+func (ownerIndexer) FromObject(obj any) (bool, []byte, error) {
+ row, ok := obj.(*GlobalRuleRow)
+ if !ok {
+ return false, nil, fmt.Errorf("unexpected object type %T", obj)
+ }
+ return true, []byte(row.Owner.String() + "\x00"), nil
+}
+
+func (ownerIndexer) FromArgs(args ...any) ([]byte, error) {
+ if len(args) != 1 {
+ return nil, fmt.Errorf("expected 1 argument, got %d", len(args))
+ }
+ owner, ok := args[0].(types.NamespacedNameKind)
+ if !ok {
+ return nil, fmt.Errorf("argument is not a NamespacedNameKind")
+ }
+ return []byte(owner.String() + "\x00"), nil
+}
diff --git a/internal/adc/cache/memdb.go b/internal/adc/cache/memdb.go
index 50f2a9f2..83db0b67 100644
--- a/internal/adc/cache/memdb.go
+++ b/internal/adc/cache/memdb.go
@@ -55,8 +55,10 @@ func (c *dbCache) Insert(obj any) error {
return c.InsertService(t)
case *types.Consumer:
return c.InsertConsumer(t)
- case *types.GlobalRuleItem:
+ case *GlobalRuleRow:
return c.InsertGlobalRule(t)
+ case *PluginMetadataRow:
+ return c.InsertPluginMetadata(t)
default:
return errors.New("unsupported type")
}
@@ -72,8 +74,10 @@ func (c *dbCache) Delete(obj any) error {
return c.DeleteService(t)
case *types.Consumer:
return c.DeleteConsumer(t)
- case *types.GlobalRuleItem:
+ case *GlobalRuleRow:
return c.DeleteGlobalRule(t)
+ case *PluginMetadataRow:
+ return c.DeletePluginMetadata(t)
default:
return errors.New("unsupported type")
}
@@ -96,10 +100,14 @@ func (c *dbCache) InsertConsumer(consumer *types.Consumer)
error {
return c.insert(types.TypeConsumer, consumer.DeepCopy())
}
-func (c *dbCache) InsertGlobalRule(globalRule *types.GlobalRuleItem) error {
+func (c *dbCache) InsertGlobalRule(globalRule *GlobalRuleRow) error {
return c.insert(types.TypeGlobalRule, globalRule.DeepCopy())
}
+func (c *dbCache) InsertPluginMetadata(pluginMetadata *PluginMetadataRow)
error {
+ return c.insert(types.TypePluginMetadata, pluginMetadata.DeepCopy())
+}
+
func (c *dbCache) insert(table string, obj any) error {
txn := c.db.Txn(true)
defer txn.Abort()
@@ -142,12 +150,20 @@ func (c *dbCache) GetConsumer(username string)
(*types.Consumer, error) {
return obj.(*types.Consumer).DeepCopy(), nil
}
-func (c *dbCache) GetGlobalRule(id string) (*types.GlobalRuleItem, error) {
+func (c *dbCache) GetGlobalRule(id string) (*GlobalRuleRow, error) {
obj, err := c.get(types.TypeGlobalRule, id)
if err != nil {
return nil, err
}
- return obj.(*types.GlobalRuleItem).DeepCopy(), nil
+ return obj.(*GlobalRuleRow).DeepCopy(), nil
+}
+
+func (c *dbCache) GetPluginMetadata(id string) (*PluginMetadataRow, error) {
+ obj, err := c.get(types.TypePluginMetadata, id)
+ if err != nil {
+ return nil, err
+ }
+ return obj.(*PluginMetadataRow).DeepCopy(), nil
}
func (c *dbCache) GetStreamRoute(id string) (*types.StreamRoute, error) {
@@ -222,18 +238,30 @@ func (c *dbCache) ListConsumers(opts ...ListOption)
([]*types.Consumer, error) {
return consumers, nil
}
-func (c *dbCache) ListGlobalRules(opts ...ListOption)
([]*types.GlobalRuleItem, error) {
+func (c *dbCache) ListGlobalRules(opts ...ListOption) ([]*GlobalRuleRow,
error) {
raws, err := c.list(types.TypeGlobalRule, opts...)
if err != nil {
return nil, err
}
- globalRules := make([]*types.GlobalRuleItem, 0, len(raws))
+ globalRules := make([]*GlobalRuleRow, 0, len(raws))
for _, raw := range raws {
- globalRules = append(globalRules,
raw.(*types.GlobalRuleItem).DeepCopy())
+ globalRules = append(globalRules,
raw.(*GlobalRuleRow).DeepCopy())
}
return globalRules, nil
}
+func (c *dbCache) ListPluginMetadata(opts ...ListOption)
([]*PluginMetadataRow, error) {
+ raws, err := c.list(types.TypePluginMetadata, opts...)
+ if err != nil {
+ return nil, err
+ }
+ pluginMetadata := make([]*PluginMetadataRow, 0, len(raws))
+ for _, raw := range raws {
+ pluginMetadata = append(pluginMetadata,
raw.(*PluginMetadataRow).DeepCopy())
+ }
+ return pluginMetadata, nil
+}
+
func (c *dbCache) list(table string, opts ...ListOption) ([]any, error) {
txn := c.db.Txn(false)
defer txn.Abort()
@@ -245,6 +273,10 @@ func (c *dbCache) list(table string, opts ...ListOption)
([]any, error) {
index = KindLabelIndex
args = []any{listOpts.KindLabelSelector.Kind,
listOpts.KindLabelSelector.Namespace, listOpts.KindLabelSelector.Name}
}
+ if listOpts.OwnerSelector != nil {
+ index = OwnerIndex
+ args = []any{listOpts.OwnerSelector.Owner}
+ }
iter, err := txn.Get(table, index, args...)
if err != nil {
return nil, err
@@ -272,10 +304,14 @@ func (c *dbCache) DeleteConsumer(consumer
*types.Consumer) error {
return c.delete(types.TypeConsumer, consumer)
}
-func (c *dbCache) DeleteGlobalRule(globalRule *types.GlobalRuleItem) error {
+func (c *dbCache) DeleteGlobalRule(globalRule *GlobalRuleRow) error {
return c.delete(types.TypeGlobalRule, globalRule)
}
+func (c *dbCache) DeletePluginMetadata(pluginMetadata *PluginMetadataRow)
error {
+ return c.delete(types.TypePluginMetadata, pluginMetadata)
+}
+
func (c *dbCache) delete(table string, obj any) error {
txn := c.db.Txn(true)
defer txn.Abort()
diff --git a/internal/adc/cache/noop_db.go b/internal/adc/cache/noop_db.go
index f18ef1ca..878c7210 100644
--- a/internal/adc/cache/noop_db.go
+++ b/internal/adc/cache/noop_db.go
@@ -45,7 +45,11 @@ func (c *noopCache) InsertService(u *types.Service) error {
return nil
}
-func (c *noopCache) InsertGlobalRule(gr *types.GlobalRuleItem) error {
+func (c *noopCache) InsertGlobalRule(gr *GlobalRuleRow) error {
+ return nil
+}
+
+func (c *noopCache) InsertPluginMetadata(pm *PluginMetadataRow) error {
return nil
}
@@ -61,7 +65,11 @@ func (c *noopCache) GetService(id string) (*types.Service,
error) {
return nil, nil
}
-func (c *noopCache) GetGlobalRule(id string) (*types.GlobalRuleItem, error) {
+func (c *noopCache) GetGlobalRule(id string) (*GlobalRuleRow, error) {
+ return nil, nil
+}
+
+func (c *noopCache) GetPluginMetadata(id string) (*PluginMetadataRow, error) {
return nil, nil
}
@@ -81,7 +89,11 @@ func (c *noopCache) ListStreamRoutes(...ListOption)
([]*types.StreamRoute, error
return nil, nil
}
-func (c *noopCache) ListGlobalRules(...ListOption) ([]*types.GlobalRuleItem,
error) {
+func (c *noopCache) ListGlobalRules(...ListOption) ([]*GlobalRuleRow, error) {
+ return nil, nil
+}
+
+func (c *noopCache) ListPluginMetadata(...ListOption) ([]*PluginMetadataRow,
error) {
return nil, nil
}
@@ -97,7 +109,11 @@ func (c *noopCache) DeleteService(u *types.Service) error {
return nil
}
-func (c *noopCache) DeleteGlobalRule(gr *types.GlobalRuleItem) error {
+func (c *noopCache) DeleteGlobalRule(gr *GlobalRuleRow) error {
+ return nil
+}
+
+func (c *noopCache) DeletePluginMetadata(pm *PluginMetadataRow) error {
return nil
}
diff --git a/internal/adc/cache/schema.go b/internal/adc/cache/schema.go
index 97c32deb..3c3a42e3 100644
--- a/internal/adc/cache/schema.go
+++ b/internal/adc/cache/schema.go
@@ -86,11 +86,20 @@ var (
Unique: true,
Indexer:
&memdb.StringFieldIndex{Field: "ID"},
},
- KindLabelIndex: {
- Name: KindLabelIndex,
- Unique: false,
- AllowMissing: true,
- Indexer: &KindLabelIndexer,
+ OwnerIndex: {
+ Name: OwnerIndex,
+ Unique: false,
+ Indexer: &ownerIndexer{},
+ },
+ },
+ },
+ "plugin_metadata": {
+ Name: "plugin_metadata",
+ Indexes: map[string]*memdb.IndexSchema{
+ "id": {
+ Name: "id",
+ Unique: true,
+ Indexer:
&memdb.StringFieldIndex{Field: "ID"},
},
},
},
diff --git a/internal/adc/cache/store.go b/internal/adc/cache/store.go
index 17a8a6d6..fb4e5192 100644
--- a/internal/adc/cache/store.go
+++ b/internal/adc/cache/store.go
@@ -19,11 +19,9 @@ package cache
import (
"cmp"
- "fmt"
"sync"
"github.com/go-logr/logr"
- "github.com/google/uuid"
adctypes "github.com/apache/apisix-ingress-controller/api/adc"
"github.com/apache/apisix-ingress-controller/internal/controller/label"
@@ -31,14 +29,14 @@ import (
)
type Store struct {
- cacheMap map[string]Cache
- pluginMetadataMap map[string]adctypes.PluginMetadata
+ cacheMap map[string]Cache
sync.Mutex
log logr.Logger
}
-// Entity is a top-level ADC resource a cacheKey holds: a service, ssl or
consumer.
+// Entity is a top-level ADC resource a cacheKey holds: a service, ssl,
consumer,
+// global_rule or plugin_metadata.
type Entity struct {
Type string
ID string
@@ -54,12 +52,23 @@ type Entity struct {
func NewStore(log logr.Logger) *Store {
return &Store{
- cacheMap: make(map[string]Cache),
- pluginMetadataMap: make(map[string]adctypes.PluginMetadata),
- log: log.WithName("store"),
+ cacheMap: make(map[string]Cache),
+ log: log.WithName("store"),
}
}
+func (s *Store) cacheFor(name string) (Cache, error) {
+ if c, ok := s.cacheMap[name]; ok {
+ return c, nil
+ }
+ db, err := NewMemDBCache()
+ if err != nil {
+ return nil, err
+ }
+ s.cacheMap[name] = db
+ return db, nil
+}
+
func ownerFromLabels(labels map[string]string) types.NamespacedNameKind {
return types.NamespacedNameKind{
Kind: labels[label.LabelKind],
@@ -68,6 +77,15 @@ func ownerFromLabels(labels map[string]string)
types.NamespacedNameKind {
}
}
+// gatewayProxyOf returns the GatewayProxy a cacheKey names.
+func gatewayProxyOf(name string) (types.NamespacedNameKind, bool) {
+ var gatewayProxy types.NamespacedNameKind
+ if err := gatewayProxy.FromString(name); err != nil {
+ return types.NamespacedNameKind{}, false
+ }
+ return gatewayProxy, true
+}
+
func childrenOf(service *adctypes.Service, owner types.NamespacedNameKind)
[]Entity {
children := make([]Entity, 0,
len(service.Routes)+len(service.StreamRoutes))
for _, route := range service.Routes {
@@ -79,17 +97,71 @@ func childrenOf(service *adctypes.Service, owner
types.NamespacedNameKind) []Ent
return children
}
+// routeOwner finds the Kubernetes resource that produced the route id, by
scanning
+// every service the cacheKey holds. A route's own labels can differ from its
service's
+// (a traffic-split service can combine rules several ApisixRoutes each
contributed),
+// so this can't reuse the service's own KindLabelSelector match.
+func routeOwner(targetCache Cache, id string) (types.NamespacedNameKind, bool)
{
+ services, err := targetCache.ListServices()
+ if err != nil {
+ return types.NamespacedNameKind{}, false
+ }
+ for _, service := range services {
+ for _, route := range service.Routes {
+ if route.ID == id {
+ return ownerFromLabels(route.GetLabels()), true
+ }
+ }
+ }
+ return types.NamespacedNameKind{}, false
+}
+
+// setGlobalRules is Insert and SetGlobalRules' shared implementation. Callers
must
+// already hold s.Lock.
+func (s *Store) setGlobalRules(targetCache Cache, owner
types.NamespacedNameKind, plugins adctypes.GlobalRule) error {
+ rows, err := targetCache.ListGlobalRules(&OwnerSelector{Owner: owner})
+ if err != nil {
+ return err
+ }
+ for _, row := range rows {
+ if err := targetCache.DeleteGlobalRule(row); err != nil {
+ return err
+ }
+ }
+ for pluginName, config := range plugins {
+ if err := targetCache.InsertGlobalRule(&GlobalRuleRow{ID:
pluginName, Owner: owner, Config: config}); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// setPluginMetadata is Insert and SetPluginMetadata's shared implementation.
Callers
+// must already hold s.Lock.
+func (s *Store) setPluginMetadata(targetCache Cache, metadata
adctypes.PluginMetadata) error {
+ rows, err := targetCache.ListPluginMetadata()
+ if err != nil {
+ return err
+ }
+ for _, row := range rows {
+ if err := targetCache.DeletePluginMetadata(row); err != nil {
+ return err
+ }
+ }
+ for pluginName, config := range metadata {
+ if err :=
targetCache.InsertPluginMetadata(&PluginMetadataRow{ID: pluginName, Config:
config}); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
func (s *Store) Insert(name string, resourceTypes []string, resources
*adctypes.Resources, Labels map[string]string) error {
s.Lock()
defer s.Unlock()
- targetCache, ok := s.cacheMap[name]
- if !ok {
- db, err := NewMemDBCache()
- if err != nil {
- return err
- }
- s.cacheMap[name] = db
- targetCache = s.cacheMap[name]
+ targetCache, err := s.cacheFor(name)
+ if err != nil {
+ return err
}
s.log.V(1).Info("Inserting resources into cache", "name", name,
"resourceTypes", resourceTypes, "Labels", Labels)
selector := &KindLabelSelector{
@@ -146,34 +218,13 @@ func (s *Store) Insert(name string, resourceTypes
[]string, resources *adctypes.
}
}
case adctypes.TypeGlobalRule:
- // List existing global rules that match the selector
- globalRules, err :=
targetCache.ListGlobalRules(selector)
- if err != nil {
+ if err := s.setGlobalRules(targetCache,
ownerFromLabels(Labels), resources.GlobalRules); err != nil {
return err
}
- // Delete existing matching global rules
- for _, globalRule := range globalRules {
- if err :=
targetCache.DeleteGlobalRule(globalRule); err != nil {
- return err
- }
- }
- // Convert GlobalRule (Plugins) to GlobalRuleItem and
insert
- if len(resources.GlobalRules) > 0 {
- id := name + "-" + uuid.NewString()
- globalRuleItem := &adctypes.GlobalRuleItem{
- Metadata: adctypes.Metadata{
- ID: id,
- Name: id,
- Labels: Labels,
- },
- Plugins:
adctypes.Plugins(resources.GlobalRules),
- }
- if err :=
targetCache.InsertGlobalRule(globalRuleItem); err != nil {
- return err
- }
- }
case adctypes.TypePluginMetadata:
- s.pluginMetadataMap[name] = resources.PluginMetadata
+ if err := s.setPluginMetadata(targetCache,
resources.PluginMetadata); err != nil {
+ return err
+ }
default:
continue
}
@@ -226,17 +277,13 @@ func (s *Store) Delete(name string, resourceTypes
[]string, Labels map[string]st
}
}
case adctypes.TypeGlobalRule:
- globalRules, err :=
targetCache.ListGlobalRules(selector)
- if err != nil {
- s.log.Error(err, "failed to list global rules")
- }
- for _, globalRule := range globalRules {
- if err :=
targetCache.DeleteGlobalRule(globalRule); err != nil {
- s.log.Error(err, "failed to delete
global rule", "global rule", globalRule.ID)
- }
+ if err := s.setGlobalRules(targetCache,
ownerFromLabels(Labels), nil); err != nil {
+ s.log.Error(err, "failed to delete global
rules")
}
case adctypes.TypePluginMetadata:
- delete(s.pluginMetadataMap, name)
+ if err := s.setPluginMetadata(targetCache, nil); err !=
nil {
+ s.log.Error(err, "failed to delete plugin
metadata")
+ }
}
}
if len(resourceTypes) == 0 {
@@ -252,22 +299,21 @@ func (s *Store) GetResources(name string)
(*adctypes.Resources, error) {
if !ok {
return &adctypes.Resources{}, nil
}
- var globalrule adctypes.GlobalRule
- var metadata adctypes.PluginMetadata
- // Get all global rules from cache and merge them
- globalRuleItems, _ := targetCache.ListGlobalRules()
- if len(globalRuleItems) > 0 {
- merged := make(adctypes.Plugins)
- for _, item := range globalRuleItems {
- for k, v := range item.Plugins {
- merged[k] = v
- }
+ var globalRules adctypes.GlobalRule
+ globalRuleRows, _ := targetCache.ListGlobalRules()
+ if len(globalRuleRows) > 0 {
+ globalRules = make(adctypes.GlobalRule, len(globalRuleRows))
+ for _, row := range globalRuleRows {
+ globalRules[row.ID] = row.Config
}
- globalrule = adctypes.GlobalRule(merged)
}
- s.log.V(1).Info("GetResources fetched global rule items", "itemCount",
len(globalRuleItems), "pluginCount", len(globalrule))
- if meta, ok := s.pluginMetadataMap[name]; ok {
- metadata = meta.DeepCopy()
+ var pluginMetadata adctypes.PluginMetadata
+ pluginMetadataRows, _ := targetCache.ListPluginMetadata()
+ if len(pluginMetadataRows) > 0 {
+ pluginMetadata = make(adctypes.PluginMetadata,
len(pluginMetadataRows))
+ for _, row := range pluginMetadataRows {
+ pluginMetadata[row.ID] = row.Config
+ }
}
consumers, _ := targetCache.ListConsumers()
services, _ := targetCache.ListServices()
@@ -276,89 +322,42 @@ func (s *Store) GetResources(name string)
(*adctypes.Resources, error) {
Consumers: consumers,
Services: services,
SSLs: ssls,
- GlobalRules: globalrule,
- PluginMetadata: metadata,
+ GlobalRules: globalRules,
+ PluginMetadata: pluginMetadata,
}, nil
}
-func (s *Store) ListGlobalRules(name string) ([]*adctypes.GlobalRuleItem,
error) {
+// SetGlobalRules replaces the global_rules plugins owner declares in the
cacheKey name
+// with plugins; an empty plugins removes all of them. A plugin name can only
be
+// configured once, so another owner's plugin of the same name is overwritten:
which
+// declaration wins is undefined.
+func (s *Store) SetGlobalRules(name string, owner types.NamespacedNameKind,
plugins adctypes.GlobalRule) error {
s.Lock()
defer s.Unlock()
- targetCache, ok := s.cacheMap[name]
- if !ok {
- return nil, fmt.Errorf("cache not found for name: %s", name)
- }
- globalRules, err := targetCache.ListGlobalRules()
+ targetCache, err := s.cacheFor(name)
if err != nil {
- return nil, fmt.Errorf("failed to list global rules: %w", err)
+ return err
}
- return globalRules, nil
+ return s.setGlobalRules(targetCache, owner, plugins)
}
-func (s *Store) GetResourceLabel(name, resourceType string, id string)
(map[string]string, error) {
+// SetPluginMetadata replaces all plugin_metadata the cacheKey name holds.
+func (s *Store) SetPluginMetadata(name string, metadata
adctypes.PluginMetadata) error {
s.Lock()
defer s.Unlock()
- targetCache, ok := s.cacheMap[name]
- if !ok {
- return nil, fmt.Errorf("cache not found for name: %s", name)
- }
- switch resourceType {
- case adctypes.TypeService:
- service, err := targetCache.GetService(id)
- if err != nil {
- return nil, fmt.Errorf("failed to get service: %w", err)
- }
- return service.Labels, nil
- case adctypes.TypeRoute:
- services, err := targetCache.ListServices()
- if err != nil {
- return nil, fmt.Errorf("failed to list services: %w",
err)
- }
- for _, service := range services {
- for _, route := range service.Routes {
- if route.ID == id {
- // Return labels from the service that
contains the route
- return route.GetLabels(), nil
- }
- }
- }
- return nil, fmt.Errorf("route not found: %s", id)
- case adctypes.TypeSSL:
- ssl, err := targetCache.GetSSL(id)
- if err != nil {
- return nil, err
- }
- if ssl != nil {
- return ssl.GetLabels(), nil
- }
- case adctypes.TypeConsumer:
- consumer, err := targetCache.GetConsumer(id)
- if err != nil {
- return nil, err
- }
- if consumer != nil {
- return consumer.Labels, nil
- }
- case adctypes.TypeGlobalRule:
- globalRule, err := targetCache.GetGlobalRule(id)
- if err != nil {
- return nil, err
- }
- if globalRule != nil {
- return globalRule.GetLabels(), nil
- }
- default:
- return nil, fmt.Errorf("unknown resource type: %s",
resourceType)
+ targetCache, err := s.cacheFor(name)
+ if err != nil {
+ return err
}
- return nil, nil
+ return s.setPluginMetadata(targetCache, metadata)
}
// Lookup finds the top-level entity of resourceType and id the cacheKey name
holds,
// along with the Kubernetes resource that produced it, read straight from the
entity's
// own stored labels (the same ones KindLabelSelector matches Insert/Delete
against, so
-// there is exactly one place this can ever disagree with what a selector
would find). It
-// covers service, ssl and consumer; global_rule and plugin_metadata still
only expose
-// GetResourceLabel, until their own storage grows the same per-entity owner
this does.
+// there is exactly one place this can ever disagree with what a selector
would find). A
+// route is not top-level, but is looked up the same way pending its own
nested-entity
+// tracking.
func (s *Store) Lookup(name, resourceType, id string) (Entity, bool) {
s.Lock()
defer s.Unlock()
@@ -385,13 +384,34 @@ func (s *Store) Lookup(name, resourceType, id string)
(Entity, bool) {
return Entity{}, false
}
return Entity{Type: resourceType, ID: id, Name: id, Owner:
ownerFromLabels(consumer.GetLabels())}, true
+ case adctypes.TypeRoute:
+ owner, ok := routeOwner(targetCache, id)
+ if !ok {
+ return Entity{}, false
+ }
+ return Entity{Type: resourceType, ID: id, Name: id, Owner:
owner}, true
+ case adctypes.TypeGlobalRule:
+ row, err := targetCache.GetGlobalRule(id)
+ if err != nil {
+ return Entity{}, false
+ }
+ return Entity{Type: resourceType, ID: id, Name: id, Owner:
row.Owner}, true
+ case adctypes.TypePluginMetadata:
+ if _, err := targetCache.GetPluginMetadata(id); err != nil {
+ return Entity{}, false
+ }
+ gatewayProxy, ok := gatewayProxyOf(name)
+ if !ok {
+ return Entity{}, false
+ }
+ return Entity{Type: resourceType, ID: id, Name: id, Owner:
gatewayProxy}, true
}
return Entity{}, false
}
-// OwnedEntities lists every service, ssl and consumer owner produced in the
cacheKey
-// name, via the same KindLabelSelector index Insert and Delete already use to
find an
-// owner's resources. See Lookup for why global_rule and plugin_metadata are
absent.
+// OwnedEntities lists every top-level entity owner produced in the cacheKey
name, via
+// the same KindLabelSelector index Insert and Delete already use for service,
ssl and
+// consumer.
func (s *Store) OwnedEntities(name string, owner types.NamespacedNameKind)
[]Entity {
s.Lock()
defer s.Unlock()
@@ -400,28 +420,36 @@ func (s *Store) OwnedEntities(name string, owner
types.NamespacedNameKind) []Ent
return nil
}
selector := &KindLabelSelector{Kind: owner.Kind, Namespace:
owner.Namespace, Name: owner.Name}
+ services, _ := targetCache.ListServices(selector)
+ ssls, _ := targetCache.ListSSL(selector)
+ consumers, _ := targetCache.ListConsumers(selector)
+ globalRules, _ := targetCache.ListGlobalRules(&OwnerSelector{Owner:
owner})
+ var pluginMetadata []*PluginMetadataRow
+ if gatewayProxy, ok := gatewayProxyOf(name); ok && gatewayProxy ==
owner {
+ pluginMetadata, _ = targetCache.ListPluginMetadata()
+ }
- var entities []Entity
- if services, err := targetCache.ListServices(selector); err == nil {
- for _, service := range services {
- entities = append(entities, Entity{
- Type: adctypes.TypeService,
- ID: service.ID,
- Name: cmp.Or(service.Name, service.ID),
- Owner: owner,
- Children: childrenOf(service, owner),
- })
- }
+ entities := make([]Entity, 0,
len(services)+len(ssls)+len(consumers)+len(globalRules)+len(pluginMetadata))
+ for _, service := range services {
+ entities = append(entities, Entity{
+ Type: adctypes.TypeService,
+ ID: service.ID,
+ Name: cmp.Or(service.Name, service.ID),
+ Owner: owner,
+ Children: childrenOf(service, owner),
+ })
}
- if ssls, err := targetCache.ListSSL(selector); err == nil {
- for _, ssl := range ssls {
- entities = append(entities, Entity{Type:
adctypes.TypeSSL, ID: ssl.ID, Name: ssl.ID, Owner: owner})
- }
+ for _, ssl := range ssls {
+ entities = append(entities, Entity{Type: adctypes.TypeSSL, ID:
ssl.ID, Name: ssl.ID, Owner: owner})
}
- if consumers, err := targetCache.ListConsumers(selector); err == nil {
- for _, consumer := range consumers {
- entities = append(entities, Entity{Type:
adctypes.TypeConsumer, ID: consumer.Username, Name: consumer.Username, Owner:
owner})
- }
+ for _, consumer := range consumers {
+ entities = append(entities, Entity{Type: adctypes.TypeConsumer,
ID: consumer.Username, Name: consumer.Username, Owner: owner})
+ }
+ for _, row := range globalRules {
+ entities = append(entities, Entity{Type:
adctypes.TypeGlobalRule, ID: row.ID, Name: row.ID, Owner: owner})
+ }
+ for _, row := range pluginMetadata {
+ entities = append(entities, Entity{Type:
adctypes.TypePluginMetadata, ID: row.ID, Name: row.ID, Owner: owner})
}
return entities
}
diff --git a/internal/adc/cache/store_test.go b/internal/adc/cache/store_test.go
index 288c6d48..1fdd46b7 100644
--- a/internal/adc/cache/store_test.go
+++ b/internal/adc/cache/store_test.go
@@ -31,6 +31,8 @@ import (
const configName = "GatewayProxy/ns/gp"
+var gatewayProxy = types.NamespacedNameKind{Kind: types.KindGatewayProxy,
Namespace: "ns", Name: "gp"}
+
func ownerNamed(kind, name string) types.NamespacedNameKind {
return types.NamespacedNameKind{Kind: kind, Namespace: "ns", Name: name}
}
@@ -55,11 +57,14 @@ func TestLookupFindsTheOwnerOfEveryTopLevelType(t
*testing.T) {
route := ownerNamed(types.KindApisixRoute, "route")
tls := ownerNamed(types.KindApisixTls, "tls")
consumerOwner := ownerNamed(types.KindConsumer, "consumer")
+ globalRule := ownerNamed(types.KindApisixGlobalRule, "global")
s := NewStore(logr.Discard())
require.NoError(t, s.Insert(configName, []string{adctypes.TypeService},
&adctypes.Resources{Services: []*adctypes.Service{service("svc", route)}},
labelsOf(route)))
require.NoError(t, s.Insert(configName, []string{adctypes.TypeSSL},
&adctypes.Resources{SSLs: []*adctypes.SSL{ssl("ssl", tls)}}, labelsOf(tls)))
require.NoError(t, s.Insert(configName,
[]string{adctypes.TypeConsumer}, &adctypes.Resources{Consumers:
[]*adctypes.Consumer{consumer("alice", consumerOwner)}},
labelsOf(consumerOwner)))
+ require.NoError(t, s.SetGlobalRules(configName, globalRule,
adctypes.GlobalRule{"prometheus": map[string]any{}}))
+ require.NoError(t, s.SetPluginMetadata(configName,
adctypes.PluginMetadata{"http-logger": map[string]any{}}))
cases := []struct {
resourceType, id, name string
@@ -68,6 +73,8 @@ func TestLookupFindsTheOwnerOfEveryTopLevelType(t *testing.T)
{
{adctypes.TypeService, "svc", "name-svc", route},
{adctypes.TypeSSL, "ssl", "ssl", tls},
{adctypes.TypeConsumer, "alice", "alice", consumerOwner},
+ {adctypes.TypeGlobalRule, "prometheus", "prometheus",
globalRule},
+ {adctypes.TypePluginMetadata, "http-logger", "http-logger",
gatewayProxy},
}
for _, tc := range cases {
t.Run(tc.resourceType, func(t *testing.T) {
@@ -80,20 +87,72 @@ func TestLookupFindsTheOwnerOfEveryTopLevelType(t
*testing.T) {
_, ok := s.Lookup(configName, adctypes.TypeService, "missing")
assert.False(t, ok)
+ _, ok = s.Lookup(configName, adctypes.TypePluginMetadata, "missing")
+ assert.False(t, ok)
_, ok = s.Lookup("GatewayProxy/ns/other", adctypes.TypeService, "svc")
assert.False(t, ok)
}
-// TestLookupHasNoOpinionOnGlobalRuleOrPluginMetadataYet documents the current
boundary:
-// their storage carries no owner yet, so Lookup can't answer for them.
-func TestLookupHasNoOpinionOnGlobalRuleOrPluginMetadataYet(t *testing.T) {
+// TestLookupFindsARouteByItsOwnLabels covers the one nested type Lookup
already
+// answers for: a route's own owner, which the service holding it doesn't
always share
+// (e.g. a traffic-split service combining rules from several ApisixRoutes).
+func TestLookupFindsARouteByItsOwnLabels(t *testing.T) {
+ svcOwner := ownerNamed(types.KindApisixRoute, "service-writer")
+ routeOwner := ownerNamed(types.KindApisixRoute, "route-writer")
s := NewStore(logr.Discard())
- require.NoError(t, s.Insert(configName,
[]string{adctypes.TypeGlobalRule}, &adctypes.Resources{GlobalRules:
adctypes.GlobalRule{"prometheus": map[string]any{}}},
labelsOf(ownerNamed(types.KindApisixGlobalRule, "global"))))
+ withRoute := service("svc", svcOwner)
+ withRoute.Routes = []*adctypes.Route{{Metadata: adctypes.Metadata{ID:
"r1", Labels: labelsOf(routeOwner)}}}
+ require.NoError(t, s.Insert(configName, []string{adctypes.TypeService},
&adctypes.Resources{Services: []*adctypes.Service{withRoute}},
labelsOf(svcOwner)))
+
+ entity, ok := s.Lookup(configName, adctypes.TypeRoute, "r1")
+ require.True(t, ok)
+ assert.Equal(t, routeOwner, entity.Owner, "the route's own owner, not
the service's")
- _, ok := s.Lookup(configName, adctypes.TypeGlobalRule, "prometheus")
+ _, ok = s.Lookup(configName, adctypes.TypeRoute, "missing")
assert.False(t, ok)
}
+func TestSetGlobalRulesReplacesOnlyThatOwnersPlugins(t *testing.T) {
+ globalRule := ownerNamed(types.KindApisixGlobalRule, "global")
+ s := NewStore(logr.Discard())
+ require.NoError(t, s.SetGlobalRules(configName, gatewayProxy,
adctypes.GlobalRule{"cors": map[string]any{"a": "b"}}))
+ require.NoError(t, s.SetGlobalRules(configName, globalRule,
adctypes.GlobalRule{"prometheus": map[string]any{}, "old": map[string]any{}}))
+ require.NoError(t, s.SetGlobalRules(configName, globalRule,
adctypes.GlobalRule{"prometheus": map[string]any{}}))
+
+ resources, err := s.GetResources(configName)
+ require.NoError(t, err)
+ assert.Equal(t, adctypes.GlobalRule{"cors": map[string]any{"a": "b"},
"prometheus": map[string]any{}}, resources.GlobalRules)
+
+ require.NoError(t, s.SetGlobalRules(configName, globalRule, nil))
+ resources, err = s.GetResources(configName)
+ require.NoError(t, err)
+ assert.Equal(t, adctypes.GlobalRule{"cors": map[string]any{"a": "b"}},
resources.GlobalRules)
+}
+
+func TestSetGlobalRulesOfTheSameNameOverwritesAndAttributesToTheLastWriter(t
*testing.T) {
+ globalRule := ownerNamed(types.KindApisixGlobalRule, "global")
+ s := NewStore(logr.Discard())
+ require.NoError(t, s.SetGlobalRules(configName, gatewayProxy,
adctypes.GlobalRule{"prometheus": map[string]any{"from": "gp"}}))
+ require.NoError(t, s.SetGlobalRules(configName, globalRule,
adctypes.GlobalRule{"prometheus": map[string]any{"from": "agr"}}))
+
+ resources, err := s.GetResources(configName)
+ require.NoError(t, err)
+ entity, ok := s.Lookup(configName, adctypes.TypeGlobalRule,
"prometheus")
+ require.True(t, ok)
+ assert.Equal(t, map[string]any{"from": "agr"},
resources.GlobalRules["prometheus"])
+ assert.Equal(t, globalRule, entity.Owner, "what is pushed and who it is
attributed to always agree")
+}
+
+func TestSetPluginMetadataReplacesEverything(t *testing.T) {
+ s := NewStore(logr.Discard())
+ require.NoError(t, s.SetPluginMetadata(configName,
adctypes.PluginMetadata{"old": map[string]any{}}))
+ require.NoError(t, s.SetPluginMetadata(configName,
adctypes.PluginMetadata{"new": map[string]any{}}))
+
+ resources, err := s.GetResources(configName)
+ require.NoError(t, err)
+ assert.Equal(t, adctypes.PluginMetadata{"new": map[string]any{}},
resources.PluginMetadata)
+}
+
// TestLookupReadsTheEntitysOwnLabelsNotInsertsArgument covers why Lookup
can't source
// the owner from anywhere but the entity's own stored labels: those are also
what
// KindLabelSelector matches Delete and a future Insert against, so this is
the only
@@ -163,3 +222,19 @@ func TestOwnedEntities(t *testing.T) {
assert.Empty(t, s.OwnedEntities(configName,
ownerNamed(types.KindApisixRoute, "nobody")))
}
+
+func TestOwnedEntitiesIncludesGlobalRulesAndPluginMetadataOfTheGatewayProxy(t
*testing.T) {
+ globalRule := ownerNamed(types.KindApisixGlobalRule, "global")
+ s := NewStore(logr.Discard())
+ require.NoError(t, s.SetGlobalRules(configName, gatewayProxy,
adctypes.GlobalRule{"cors": map[string]any{}}))
+ require.NoError(t, s.SetGlobalRules(configName, globalRule,
adctypes.GlobalRule{"prometheus": map[string]any{}}))
+ require.NoError(t, s.SetPluginMetadata(configName,
adctypes.PluginMetadata{"http-logger": map[string]any{}}))
+
+ gpEntities := s.OwnedEntities(configName, gatewayProxy)
+ assert.Len(t, gpEntities, 2, "the GatewayProxy's own global rule and
the cacheKey's plugin metadata")
+
+ agrEntities := s.OwnedEntities(configName, globalRule)
+ require.Len(t, agrEntities, 1)
+ assert.Equal(t, adctypes.TypeGlobalRule, agrEntities[0].Type)
+ assert.Equal(t, "prometheus", agrEntities[0].ID)
+}
diff --git a/internal/provider/apisix/status.go
b/internal/provider/apisix/status.go
index 0aeb58ce..40f3fc22 100644
--- a/internal/provider/apisix/status.go
+++ b/internal/provider/apisix/status.go
@@ -30,7 +30,6 @@ import (
adctypes "github.com/apache/apisix-ingress-controller/api/adc"
apiv1alpha1 "github.com/apache/apisix-ingress-controller/api/v1alpha1"
apiv2 "github.com/apache/apisix-ingress-controller/api/v2"
- "github.com/apache/apisix-ingress-controller/internal/controller/label"
"github.com/apache/apisix-ingress-controller/internal/controller/status"
cutils
"github.com/apache/apisix-ingress-controller/internal/controller/utils"
"github.com/apache/apisix-ingress-controller/internal/types"
@@ -122,23 +121,13 @@ func (d *apisixProvider) classifySyncResult(
anyUnattributed := false
for _, syncStatus := range addrErr.FailedStatuses {
- if syncStatus.Event.ResourceType == "" {
+ entity, ok := d.store.Lookup(configName,
syncStatus.Event.ResourceType, syncStatus.Event.ResourceID)
+ if !ok {
anyUnattributed = true
continue
}
- labels, err :=
d.store.GetResourceLabel(configName, syncStatus.Event.ResourceType,
syncStatus.Event.ResourceID)
- if err != nil {
- d.log.Error(err, "failed to get
resource label",
- "configName", configName,
"resourceType", syncStatus.Event.ResourceType, "id",
syncStatus.Event.ResourceID)
- continue
- }
- resourceKey := types.NamespacedNameKind{
- Name: labels[label.LabelName],
- Namespace: labels[label.LabelNamespace],
- Kind: labels[label.LabelKind],
- }
msg := fmt.Sprintf("ServerAddr: %s, Error: %s",
addrErr.ServerAddr, syncStatus.Reason)
- resourceFailures[resourceKey] =
append(resourceFailures[resourceKey], msg)
+ resourceFailures[entity.Owner] =
append(resourceFailures[entity.Owner], msg)
}
if anyUnattributed && endpointMsg == "" {
gatewayProxyMsgs = append(gatewayProxyMsgs,
addrErr.Error())
diff --git a/internal/provider/apisix/status_test.go
b/internal/provider/apisix/status_test.go
index 81fa567d..fa5f343c 100644
--- a/internal/provider/apisix/status_test.go
+++ b/internal/provider/apisix/status_test.go
@@ -271,18 +271,14 @@ func
TestClassifySyncResultEndpointFailuresGoToGatewayProxy(t *testing.T) {
func TestClassifySyncResultAttributesFailedStatusesToTheirResource(t
*testing.T) {
d := &apisixProvider{log: logr.Discard(), store:
cache.NewStore(logr.Discard())}
const configName = "GatewayProxy/ns/gp"
+ owner := map[string]string{
+ label.LabelKind: "ApisixRoute",
+ label.LabelName: "route1",
+ label.LabelNamespace: "ns1",
+ }
if err := d.store.Insert(configName, []string{adctypes.TypeService},
&adctypes.Resources{
- Services: []*adctypes.Service{{
- Metadata: adctypes.Metadata{
- ID: "svc1",
- Labels: map[string]string{
- label.LabelKind: "ApisixRoute",
- label.LabelName: "route1",
- label.LabelNamespace: "ns1",
- },
- },
- }},
- }, nil); err != nil {
+ Services: []*adctypes.Service{{Metadata: adctypes.Metadata{ID:
"svc1", Labels: owner}}},
+ }, owner); err != nil {
t.Fatalf("seeding the store: %v", err)
}
@@ -319,18 +315,14 @@ func
TestClassifySyncResultReportsEndpointStatusesEvenOnAFullyAttributedAddrErr(
// endpoint failure too.
d := &apisixProvider{log: logr.Discard(), store:
cache.NewStore(logr.Discard())}
const configName = "GatewayProxy/ns/gp"
+ owner := map[string]string{
+ label.LabelKind: "ApisixRoute",
+ label.LabelName: "route1",
+ label.LabelNamespace: "ns1",
+ }
if err := d.store.Insert(configName, []string{adctypes.TypeService},
&adctypes.Resources{
- Services: []*adctypes.Service{{
- Metadata: adctypes.Metadata{
- ID: "svc1",
- Labels: map[string]string{
- label.LabelKind: "ApisixRoute",
- label.LabelName: "route1",
- label.LabelNamespace: "ns1",
- },
- },
- }},
- }, nil); err != nil {
+ Services: []*adctypes.Service{{Metadata: adctypes.Metadata{ID:
"svc1", Labels: owner}}},
+ }, owner); err != nil {
t.Fatalf("seeding the store: %v", err)
}
@@ -367,7 +359,7 @@ func
TestClassifySyncResultReportsEndpointStatusesEvenOnAFullyAttributedAddrErr(
func
TestClassifySyncResultFallsBackToGatewayProxyWhenAFailedStatusHasNoResourceAttribution(t
*testing.T) {
// apisix-standalone: FailedStatuses can be non-empty yet carry no
Event to resolve a
// resource from at all, the whole addrErr is then a GatewayProxy-level
signal.
- d := &apisixProvider{log: logr.Discard()}
+ d := &apisixProvider{log: logr.Discard(), store:
cache.NewStore(logr.Discard())}
execErrs := types.ADCExecutionErrors{Errors: []types.ADCExecutionError{{
Name: "GatewayProxy/ns/gp",
FailedErrors: []types.ADCExecutionServerAddrError{{