@@ -33,19 +33,15 @@ import (
3333 "github.com/gorilla/securecookie"
3434 "golang.org/x/oauth2"
3535 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
36- "k8s.io/apimachinery/pkg/labels"
3736 "k8s.io/apimachinery/pkg/runtime"
38- "k8s.io/apimachinery/pkg/runtime/schema"
3937 componentbaseversion "k8s.io/component-base/version"
4038 "k8s.io/klog/v2"
4139
4240 "github.com/kube-bind/kube-bind/backend/kubernetes"
43- "github.com/kube-bind/kube-bind/backend/kubernetes/resources"
4441 "github.com/kube-bind/kube-bind/backend/session"
4542 "github.com/kube-bind/kube-bind/backend/template"
4643 bindversion "github.com/kube-bind/kube-bind/pkg/version"
4744 kubebindv1alpha2 "github.com/kube-bind/kube-bind/sdk/apis/kubebind/v1alpha2"
48- "github.com/kube-bind/kube-bind/sdk/apis/kubebind/v1alpha2/helpers"
4945)
5046
5147var (
@@ -346,12 +342,14 @@ func createSessionState(authCode *AuthCode, token *oauth2.Token) (*session.State
346342}
347343
348344type UISchema struct {
349- Name string
350- Version string
351- Group string
352- Kind string
353- Scope string // "Namespaced" or "Cluster"
354- Resource string
345+ Scope string // "Namespaced" or "Cluster"
346+
347+ Name string
348+ Description string
349+
350+ Resources []kubebindv1alpha2.APIServiceExportResource
351+ PermissionClaims []kubebindv1alpha2.PermissionClaim
352+ Namespaces []kubebindv1alpha2.Namespaces
355353
356354 // SessionID
357355 SessionID string
@@ -376,44 +374,26 @@ func (h *handler) handleResources(w http.ResponseWriter, r *http.Request) {
376374 return
377375 }
378376
379- exportedSchemas , err := h .getBackendDynamicResource (r .Context (), providerCluster )
377+ templates , err := h .listCollectionTemplates (r .Context (), providerCluster )
380378 if err != nil {
381- logger .Error (err , "failed to get dynamic resources" )
379+ logger .Error (err , "failed to get template resources" )
382380 http .Error (w , "internal error" , http .StatusInternalServerError )
383381 return
384382 }
385383
386- result := make ([]UISchema , 0 , len (exportedSchemas ))
387- for _ , item := range exportedSchemas {
384+ result := make ([]UISchema , 0 , len (templates . Items ))
385+ for _ , item := range templates . Items {
388386 if ! strings .EqualFold (h .scope .String (), string (item .Spec .Scope )) && h .scope != kubebindv1alpha2 .ClusterScope {
389387 continue
390388 }
391389
392- if len (item .Spec .Versions ) == 0 {
393- logger .Error (fmt .Errorf ("no versions found" ), "skipping schema" , "name" , item .Name )
394- continue
395- }
396- // pick first served version
397- ver := ""
398- for _ , v := range item .Spec .Versions {
399- if v .Served {
400- ver = v .Name
401- break
402- }
403- }
404- if ver == "" {
405- logger .Error (fmt .Errorf ("no served versions found" ), "skipping schema" , "name" , item .Name )
406- continue
407- }
408390 result = append (result , UISchema {
409- Name : item .GetName (),
410- Kind : item .Spec .Names .Kind ,
411- Scope : string (item .Spec .Scope ),
412- Version : ver ,
413- Group : item .Spec .Group ,
414- // Important: This MUST be used as UI button class in the url, so tests can 'click it' based on it.
415- Resource : item .Spec .Names .Plural ,
416- SessionID : sessionID ,
391+ Name : item .GetName (),
392+ Scope : string (item .Spec .Scope ),
393+ PermissionClaims : item .Spec .PermissionClaims ,
394+ Resources : item .Spec .Resources ,
395+ Namespaces : item .Spec .Namespaces ,
396+ SessionID : sessionID ,
417397 })
418398 }
419399
@@ -436,9 +416,7 @@ func (h *handler) handleResources(w http.ResponseWriter, r *http.Request) {
436416
437417func (h * handler ) handleBind (w http.ResponseWriter , r * http.Request ) {
438418 logger := getLogger (r )
439- group := r .URL .Query ().Get ("group" )
440- resource := r .URL .Query ().Get ("resource" )
441- version := r .URL .Query ().Get ("version" )
419+ templateName := r .URL .Query ().Get ("template" )
442420 providerCluster := mux .Vars (r )["cluster" ]
443421
444422 prepareNoCache (w )
@@ -466,24 +444,26 @@ func (h *handler) handleBind(w http.ResponseWriter, r *http.Request) {
466444 return
467445 }
468446
447+ // Module consist of many resources and permissionClaims. Read it and translate to
448+ template , err := h .kubeManager .GetTemplates (r .Context (), providerCluster , templateName )
449+ if err != nil {
450+ logger .Error (err , "failed to get template" )
451+ http .Error (w , "internal error" , http .StatusInternalServerError )
452+ return
453+ }
454+
469455 request := kubebindv1alpha2.APIServiceExportRequestResponse {
470456 TypeMeta : metav1.TypeMeta {
471457 APIVersion : kubebindv1alpha2 .SchemeGroupVersion .String (),
472458 Kind : "APIServiceExportRequest" ,
473459 },
474460 ObjectMeta : kubebindv1alpha2.NameObjectMeta {
475- // this is good for one resource. If there are more (in the future),
476- // we need a better name heuristic. Note: it does not have to be unique.
477- // But pretty is better.
478- Name : resource + "." + group ,
461+ Name : templateName ,
479462 },
480463 Spec : kubebindv1alpha2.APIServiceExportRequestSpec {
481- Resources : []kubebindv1alpha2.APIServiceExportRequestResource {
482- {
483- GroupResource : kubebindv1alpha2.GroupResource {Group : group , Resource : resource },
484- Versions : []string {version },
485- },
486- },
464+ Resources : template .Spec .Resources ,
465+ PermissionClaims : template .Spec .PermissionClaims ,
466+ Namespaces : template .Spec .Namespaces ,
487467 },
488468 }
489469
@@ -543,34 +523,26 @@ func mustRead(f func(name string) ([]byte, error), name string) string {
543523 return string (bs )
544524}
545525
546- func (h * handler ) getBackendDynamicResource (ctx context.Context , cluster string ) (kubebindv1alpha2.ExportedSchemas , error ) {
547- labelSelector := labels.Set {
548- resources .ExportedCRDsLabel : "true" ,
549- }
550-
551- parts := strings .SplitN (h .schemaSource , "." , 3 )
552- if len (parts ) != 3 { // We check this in validation, but just in case.
553- return nil , fmt .Errorf ("invalid schema source: %q" , h .schemaSource )
554- }
555-
556- gvk := schema.GroupVersionKind {
557- Kind : parts [0 ],
558- Version : parts [1 ],
559- Group : parts [2 ],
560- }
561- list , err := h .kubeManager .ListDynamicResources (ctx , cluster , gvk , labelSelector .AsSelector ())
526+ // listCollectionTemplates fetches the list of Collections from the backend cluster.
527+ // Flow is:
528+ // 1. List Collection and check what modules we are targeting
529+ // 2. Get templates from the backend cluster and construct shallow-bound schemas (no crd content).
530+ func (h * handler ) listCollectionTemplates (ctx context.Context , cluster string ) (* kubebindv1alpha2.APIServiceExportTemplateList , error ) {
531+ collections , err := h .kubeManager .ListCollections (ctx , cluster )
562532 if err != nil {
563- return nil , fmt .Errorf ("failed to list resources : %w" , err )
533+ return nil , fmt .Errorf ("failed to list collections : %w" , err )
564534 }
565535
566- boundSchemas := make (kubebindv1alpha2.ExportedSchemas , len (list .Items ))
567- for _ , item := range list .Items {
568- boundSchema , err := helpers .UnstructuredToBoundSchema (item )
569- if err != nil {
570- return nil , err
536+ templates := & kubebindv1alpha2.APIServiceExportTemplateList {}
537+ for _ , collection := range collections .Items {
538+ for _ , t := range collection .Spec .Templates {
539+ template , err := h .kubeManager .GetTemplates (ctx , cluster , t .Name )
540+ if err != nil {
541+ return nil , fmt .Errorf ("failed to get template %q: %w" , t .Name , err )
542+ }
543+ templates .Items = append (templates .Items , * template )
571544 }
572- boundSchemas [boundSchema .ResourceGroupName ()] = boundSchema
573545 }
574546
575- return boundSchemas , nil
547+ return templates , nil
576548}
0 commit comments