Skip to content

Commit 44af52a

Browse files
committed
wip: add handling for APIBindings
1 parent 8ac877a commit 44af52a

File tree

2 files changed

+106
-21
lines changed

2 files changed

+106
-21
lines changed

pkg/dynamicrestmapper/dynamicrestmapper_controller.go

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,8 @@ import (
2020
"context"
2121
"encoding/json"
2222
"fmt"
23-
"sync"
2423
"time"
2524

26-
kcpapiextensionsclientset "github.com/kcp-dev/client-go/apiextensions/client"
27-
kcpapiextensionsv1informers "github.com/kcp-dev/client-go/apiextensions/informers/apiextensions/v1"
28-
29-
kcpcache "github.com/kcp-dev/apimachinery/v2/pkg/cache"
30-
3125
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3226
"k8s.io/apimachinery/pkg/api/meta"
3327
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -36,7 +30,15 @@ import (
3630
"k8s.io/client-go/util/workqueue"
3731
"k8s.io/klog/v2"
3832

33+
kcpcache "github.com/kcp-dev/apimachinery/v2/pkg/cache"
34+
kcpapiextensionsv1informers "github.com/kcp-dev/client-go/apiextensions/informers/apiextensions/v1"
35+
"github.com/kcp-dev/logicalcluster/v3"
36+
37+
"github.com/kcp-dev/kcp/pkg/indexers"
38+
"github.com/kcp-dev/kcp/pkg/informer"
3939
"github.com/kcp-dev/kcp/pkg/logging"
40+
apisv1alpha1 "github.com/kcp-dev/kcp/sdk/apis/apis/v1alpha1"
41+
apisv1alpha1informers "github.com/kcp-dev/kcp/sdk/client/informers/externalversions/apis/v1alpha1"
4042
)
4143

4244
const (
@@ -46,8 +48,12 @@ const (
4648
func NewController(
4749
ctx context.Context,
4850
state *DynamicRESTMapper,
49-
crdClusterClient *kcpapiextensionsclientset.ClusterClientset,
5051
crdInformer kcpapiextensionsv1informers.CustomResourceDefinitionClusterInformer,
52+
apiBindingInformer apisv1alpha1informers.APIBindingClusterInformer,
53+
apiExportInformer apisv1alpha1informers.APIExportClusterInformer,
54+
apiResourceSchemaInformer apisv1alpha1informers.APIResourceSchemaClusterInformer,
55+
globalAPIExportInformer apisv1alpha1informers.APIExportClusterInformer,
56+
globalAPIResourceSchemaInformer apisv1alpha1informers.APIResourceSchemaClusterInformer,
5157
) (*Controller, error) {
5258
queue := workqueue.NewTypedRateLimitingQueueWithConfig(
5359
workqueue.DefaultTypedControllerRateLimiter[string](),
@@ -58,10 +64,19 @@ func NewController(
5864

5965
c := &Controller{
6066
queue: queue,
67+
state: state,
6168

62-
crdInformer: crdInformer,
69+
getAPIExportByPath: func(path logicalcluster.Path, name string) (*apisv1alpha1.APIExport, error) {
70+
return indexers.ByPathAndNameWithFallback[*apisv1alpha1.APIExport](
71+
apisv1alpha1.Resource("apiexports"),
72+
apiExportInformer.Informer().GetIndexer(),
73+
globalAPIExportInformer.Informer().GetIndexer(),
74+
path,
75+
name,
76+
)
77+
},
6378

64-
state: state,
79+
getAPIResourceSchema: informer.NewScopedGetterWithFallback(apiResourceSchemaInformer.Lister(), globalAPIResourceSchemaInformer.Lister()),
6580
}
6681

6782
_, _ = crdInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
@@ -76,6 +91,18 @@ func NewController(
7691
},
7792
})
7893

94+
_, _ = apiBindingInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
95+
AddFunc: func(obj interface{}) {
96+
c.enqueueAPIBinding(obj.(*apisv1alpha1.APIBinding), false)
97+
},
98+
DeleteFunc: func(obj interface{}) {
99+
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
100+
obj = tombstone.Obj
101+
}
102+
c.enqueueAPIBinding(obj.(*apisv1alpha1.APIBinding), true)
103+
},
104+
})
105+
79106
return c, nil
80107
}
81108

@@ -84,12 +111,11 @@ func NewController(
84111
// updates the workspace index, which maps logical clusters to shard URLs.
85112
type Controller struct {
86113
queue workqueue.TypedRateLimitingInterface[string]
114+
state *DynamicRESTMapper
87115

88-
crdInformer kcpapiextensionsv1informers.CustomResourceDefinitionClusterInformer
89-
90-
lock sync.RWMutex
116+
getAPIExportByPath func(path logicalcluster.Path, name string) (*apisv1alpha1.APIExport, error)
91117

92-
state *DynamicRESTMapper
118+
getAPIResourceSchema func(clusterName logicalcluster.Name, name string) (*apisv1alpha1.APIResourceSchema, error)
93119
}
94120

95121
type gvkrKey struct {
@@ -138,6 +164,56 @@ func (c *Controller) enqueueCRD(crd *apiextensionsv1.CustomResourceDefinition, d
138164
}
139165
}
140166

167+
func (c *Controller) enqueueAPIBinding(apiBinding *apisv1alpha1.APIBinding, deleted bool) {
168+
key, err := kcpcache.DeletionHandlingMetaClusterNamespaceKeyFunc(apiBinding)
169+
if err != nil {
170+
utilruntime.HandleError(err)
171+
return
172+
}
173+
174+
apiExportPath := logicalcluster.NewPath(apiBinding.Spec.Reference.Export.Path)
175+
if apiExportPath.Empty() {
176+
apiExportPath = logicalcluster.From(apiBinding).Path()
177+
}
178+
179+
apiExport, err := c.getAPIExportByPath(apiExportPath, apiBinding.Spec.Reference.Export.Name)
180+
if err != nil {
181+
utilruntime.HandleError(err)
182+
return
183+
}
184+
185+
for _, schemaName := range apiExport.Spec.LatestResourceSchemas {
186+
sch, err := c.getAPIResourceSchema(logicalcluster.From(apiExport), schemaName)
187+
if err != nil {
188+
fmt.Printf("\n\n!!! X key=%s,apiExportPath=%s,logicalcluster.From(apiExport)=%s\n\n", key, apiExportPath, logicalcluster.From(apiExport))
189+
utilruntime.HandleError(err)
190+
return
191+
}
192+
193+
for _, schVersion := range sch.Spec.Versions {
194+
encodedGvkKey, err := encodeGvkrKey(
195+
gvkrKey{
196+
Gvkr: gvkr{
197+
Group: sch.Spec.Group,
198+
Version: schVersion.Name,
199+
Kind: sch.Spec.Names.Kind,
200+
ResourcePlural: sch.Spec.Names.Plural,
201+
ResourceSingular: sch.Spec.Names.Singular,
202+
},
203+
Key: key,
204+
Deleted: deleted,
205+
},
206+
)
207+
if err != nil {
208+
utilruntime.HandleError(fmt.Errorf("%q controller failed encode APIResourceSchema object with key %q, err: %w", ControllerName, key, err))
209+
}
210+
logging.WithQueueKey(logging.WithReconciler(klog.Background(), ControllerName), encodedGvkKey).V(4).
211+
Info("queueing APIResourceSchema because of APIBinding")
212+
c.queue.Add(encodedGvkKey)
213+
}
214+
}
215+
}
216+
141217
func (c *Controller) Start(ctx context.Context, numThreads int) {
142218
defer utilruntime.HandleCrash()
143219
defer c.queue.ShutDown()

pkg/server/controllers.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,13 +1599,14 @@ func (s *Server) installDynamicRESTMapper(ctx context.Context, config *rest.Conf
15991599
config = rest.CopyConfig(config)
16001600
config = rest.AddUserAgent(config, dynamicrestmapper.ControllerName)
16011601

1602-
crdClusterClient, err := kcpapiextensionsclientset.NewForConfig(config)
1603-
if err != nil {
1604-
return err
1605-
}
1606-
1607-
c, err := dynamicrestmapper.NewController(ctx, s.DynRESTMapper, crdClusterClient,
1608-
s.ApiExtensionsSharedInformerFactory.Apiextensions().V1().CustomResourceDefinitions())
1602+
c, err := dynamicrestmapper.NewController(ctx, s.DynRESTMapper,
1603+
s.ApiExtensionsSharedInformerFactory.Apiextensions().V1().CustomResourceDefinitions(),
1604+
s.KcpSharedInformerFactory.Apis().V1alpha1().APIBindings(),
1605+
s.KcpSharedInformerFactory.Apis().V1alpha1().APIExports(),
1606+
s.KcpSharedInformerFactory.Apis().V1alpha1().APIResourceSchemas(),
1607+
s.CacheKcpSharedInformerFactory.Apis().V1alpha1().APIExports(),
1608+
s.CacheKcpSharedInformerFactory.Apis().V1alpha1().APIResourceSchemas(),
1609+
)
16091610
if err != nil {
16101611
return err
16111612
}
@@ -1614,7 +1615,15 @@ func (s *Server) installDynamicRESTMapper(ctx context.Context, config *rest.Conf
16141615
Name: dynamicrestmapper.ControllerName,
16151616
Wait: func(ctx context.Context, s *Server) error {
16161617
return wait.PollUntilContextCancel(ctx, waitPollInterval, true, func(ctx context.Context) (bool, error) {
1617-
return s.ApiExtensionsSharedInformerFactory.Apiextensions().V1().CustomResourceDefinitions().Informer().HasSynced(), nil
1618+
return s.ApiExtensionsSharedInformerFactory.Apiextensions().V1().CustomResourceDefinitions().Informer().HasSynced() &&
1619+
// APIExport
1620+
s.KcpSharedInformerFactory.Apis().V1alpha1().APIExports().Informer().HasSynced() &&
1621+
s.CacheKcpSharedInformerFactory.Apis().V1alpha1().APIExports().Informer().HasSynced() &&
1622+
// APIResourceSchema
1623+
s.KcpSharedInformerFactory.Apis().V1alpha1().APIResourceSchemas().Informer().HasSynced() &&
1624+
s.CacheKcpSharedInformerFactory.Apis().V1alpha1().APIResourceSchemas().Informer().HasSynced() &&
1625+
// APIBinding
1626+
s.KcpSharedInformerFactory.Apis().V1alpha1().APIBindings().Informer().HasSynced(), nil
16181627
})
16191628
},
16201629
Runner: func(ctx context.Context) {

0 commit comments

Comments
 (0)