44 "context"
55 "encoding/json"
66 "fmt"
7+ "net/http"
78
89 catalogd "github.com/operator-framework/catalogd/api/core/v1alpha1"
910 "github.com/operator-framework/deppy/pkg/deppy"
@@ -15,15 +16,35 @@ import (
1516 "github.com/operator-framework/operator-controller/internal/resolution/entities"
1617)
1718
19+ const catalogdOnClusterBaseURL = "http://catalogd-catalogserver.catalogd-system.svc"
20+
1821// CatalogdEntitySource is a source for(/collection of) deppy defined input.Entity, built from content
1922// made accessible on-cluster by https://github.com/operator-framework/catalogd.
2023// It is an implementation of deppy defined input.EntitySource
2124type CatalogdEntitySource struct {
22- client client.Client
25+ client client.Client
26+ baseURL string
2327}
2428
25- func NewCatalogdEntitySource (client client.Client ) * CatalogdEntitySource {
26- return & CatalogdEntitySource {client : client }
29+ type CatalogdEntitySourceOpt func (es * CatalogdEntitySource )
30+
31+ func WithBaseURL (baseURL string ) CatalogdEntitySourceOpt {
32+ return func (es * CatalogdEntitySource ) {
33+ es .baseURL = baseURL
34+ }
35+ }
36+
37+ func NewCatalogdEntitySource (client client.Client , opts ... CatalogdEntitySourceOpt ) * CatalogdEntitySource {
38+ ces := & CatalogdEntitySource {
39+ client : client ,
40+ baseURL : catalogdOnClusterBaseURL ,
41+ }
42+
43+ for _ , opt := range opts {
44+ opt (ces )
45+ }
46+
47+ return ces
2748}
2849
2950func (es * CatalogdEntitySource ) Get (_ context.Context , _ deppy.Identifier ) (* input.Entity , error ) {
@@ -32,7 +53,7 @@ func (es *CatalogdEntitySource) Get(_ context.Context, _ deppy.Identifier) (*inp
3253
3354func (es * CatalogdEntitySource ) Filter (ctx context.Context , filter input.Predicate ) (input.EntityList , error ) {
3455 resultSet := input.EntityList {}
35- entities , err := getEntities (ctx , es .client )
56+ entities , err := getEntities (ctx , es .client , es . baseURL )
3657 if err != nil {
3758 return nil , err
3859 }
@@ -45,7 +66,7 @@ func (es *CatalogdEntitySource) Filter(ctx context.Context, filter input.Predica
4566}
4667
4768func (es * CatalogdEntitySource ) GroupBy (ctx context.Context , fn input.GroupByFunction ) (input.EntityListMap , error ) {
48- entities , err := getEntities (ctx , es .client )
69+ entities , err := getEntities (ctx , es .client , es . baseURL )
4970 if err != nil {
5071 return nil , err
5172 }
@@ -60,7 +81,7 @@ func (es *CatalogdEntitySource) GroupBy(ctx context.Context, fn input.GroupByFun
6081}
6182
6283func (es * CatalogdEntitySource ) Iterate (ctx context.Context , fn input.IteratorFunction ) error {
63- entities , err := getEntities (ctx , es .client )
84+ entities , err := getEntities (ctx , es .client , es . baseURL )
6485 if err != nil {
6586 return err
6687 }
@@ -72,15 +93,15 @@ func (es *CatalogdEntitySource) Iterate(ctx context.Context, fn input.IteratorFu
7293 return nil
7394}
7495
75- func getEntities (ctx context.Context , cl client.Client ) (input.EntityList , error ) {
96+ func getEntities (ctx context.Context , cl client.Client , baseURL string ) (input.EntityList , error ) {
7697 allEntitiesList := input.EntityList {}
7798
7899 var catalogList catalogd.CatalogList
79100 if err := cl .List (ctx , & catalogList ); err != nil {
80101 return nil , err
81102 }
82103 for _ , catalog := range catalogList .Items {
83- channels , bundles , err := fetchCatalogMetadata (ctx , cl , catalog .Name )
104+ channels , bundles , err := fetchCatalogMetadata (ctx , baseURL , catalog .Name )
84105 if err != nil {
85106 return nil , err
86107 }
@@ -152,12 +173,12 @@ func MetadataToEntities(catalogName string, channels []declcfg.Channel, bundles
152173 return entityList , nil
153174}
154175
155- func fetchCatalogMetadata (ctx context.Context , cl client. Client , catalogName string ) ([]declcfg.Channel , []declcfg.Bundle , error ) {
156- channels , err := fetchCatalogMetadataByScheme [declcfg.Channel ](ctx , cl , declcfg .SchemaChannel , catalogName )
176+ func fetchCatalogMetadata (ctx context.Context , baseURL , catalogName string ) ([]declcfg.Channel , []declcfg.Bundle , error ) {
177+ channels , err := fetchCatalogMetadataByScheme [declcfg.Channel ](ctx , baseURL , declcfg .SchemaChannel , catalogName )
157178 if err != nil {
158179 return nil , nil , err
159180 }
160- bundles , err := fetchCatalogMetadataByScheme [declcfg.Bundle ](ctx , cl , declcfg .SchemaBundle , catalogName )
181+ bundles , err := fetchCatalogMetadataByScheme [declcfg.Bundle ](ctx , baseURL , declcfg .SchemaBundle , catalogName )
161182 if err != nil {
162183 return nil , nil , err
163184 }
@@ -169,21 +190,40 @@ type declcfgSchema interface {
169190 declcfg.Package | declcfg.Bundle | declcfg.Channel
170191}
171192
193+ const catalogdOnClusterURLTemplate = "%s/catalogs/%s/all.json"
194+
172195// TODO: Cleanup once https://github.com/golang/go/issues/45380 implemented
173196// We should be able to get rid of the schema arg and switch based on the type passed to this generic
174- func fetchCatalogMetadataByScheme [T declcfgSchema ](ctx context.Context , cl client.Client , schema , catalogName string ) ([]T , error ) {
175- cmList := catalogd.CatalogMetadataList {}
176- if err := cl .List (ctx , & cmList , client.MatchingLabels {"schema" : schema , "catalog" : catalogName }); err != nil {
177- return nil , err
197+ func fetchCatalogMetadataByScheme [T declcfgSchema ](ctx context.Context , baseURL , schema , catalogName string ) ([]T , error ) {
198+ contents := []T {}
199+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , fmt .Sprintf (catalogdOnClusterURLTemplate , baseURL , catalogName ), nil )
200+ if err != nil {
201+ return nil , fmt .Errorf ("error forming request: %s" , err )
178202 }
179203
180- contents := []T {}
181- for _ , cm := range cmList .Items {
182- var content T
183- if err := json .Unmarshal (cm .Spec .Content , & content ); err != nil {
184- return nil , err
204+ resp , err := http .DefaultClient .Do (req )
205+ if err != nil {
206+ return nil , fmt .Errorf ("error performing request: %s" , err )
207+ }
208+ defer resp .Body .Close ()
209+
210+ err = declcfg .WalkMetasReader (resp .Body , func (meta * declcfg.Meta , err error ) error {
211+ if err != nil {
212+ return err
213+ }
214+
215+ if meta .Schema == schema {
216+ var content T
217+ if err := json .Unmarshal (meta .Blob , & content ); err != nil {
218+ return fmt .Errorf ("error unmarshalling content: %s" , err )
219+ }
220+ contents = append (contents , content )
185221 }
186- contents = append (contents , content )
222+
223+ return nil
224+ })
225+ if err != nil {
226+ return nil , fmt .Errorf ("error processing response: %s" , err )
187227 }
188228
189229 return contents , nil
0 commit comments