Skip to content

Commit 96b4181

Browse files
authored
Merge pull request #280 from dinhxuanvu/dep-registry-comb
fix(registry): Fix dependency load/query and add ListBundles to registry client
2 parents f170e90 + c173bd6 commit 96b4181

File tree

12 files changed

+335
-23
lines changed

12 files changed

+335
-23
lines changed

configmap.example.yaml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6341,6 +6341,23 @@ data:
63416341
fieldRef:
63426342
fieldPath: metadata.name
63436343
customresourcedefinitions:
6344+
required:
6345+
- name: etcdclusters.etcd.database.coreos.com
6346+
version: v1beta2
6347+
kind: EtcdCluster
6348+
displayName: etcd Cluster
6349+
description: Represents a cluster of etcd nodes.
6350+
resources:
6351+
- kind: Service
6352+
version: v1
6353+
- kind: Pod
6354+
version: v1
6355+
specDescriptors:
6356+
- description: The desired number of member Pods for the etcd cluster.
6357+
displayName: Size
6358+
path: size
6359+
x-descriptors:
6360+
- 'urn:alm:descriptor:com.tectonic.ui:podCount'
63446361
owned:
63456362
- name: etcdclusters.etcd.database.coreos.com
63466363
version: v1beta2
@@ -7264,5 +7281,3 @@ data:
72647281
channels:
72657282
- name: alpha
72667283
currentCSV: prometheusoperator.0.22.2
7267-
7268-

pkg/client/client.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package client
22

33
import (
44
"context"
5+
"io"
56
"time"
67

78
"google.golang.org/grpc"
@@ -16,6 +17,7 @@ type Interface interface {
1617
GetBundleInPackageChannel(ctx context.Context, packageName, channelName string) (*api.Bundle, error)
1718
GetReplacementBundleInPackageChannel(ctx context.Context, currentName, packageName, channelName string) (*api.Bundle, error)
1819
GetBundleThatProvides(ctx context.Context, group, version, kind string) (*api.Bundle, error)
20+
ListBundles(ctx context.Context) (*BundleIterator, error)
1921
HealthCheck(ctx context.Context, reconnectTimeout time.Duration) (bool, error)
2022
Close() error
2123
}
@@ -28,6 +30,37 @@ type Client struct {
2830

2931
var _ Interface = &Client{}
3032

33+
type BundleStream interface {
34+
Recv() (*api.Bundle, error)
35+
}
36+
37+
type BundleIterator struct {
38+
stream BundleStream
39+
error error
40+
}
41+
42+
func NewBundleIterator(stream BundleStream) *BundleIterator {
43+
return &BundleIterator{stream: stream}
44+
}
45+
46+
func (it *BundleIterator) Next() *api.Bundle {
47+
if it.error != nil {
48+
return nil
49+
}
50+
next, err := it.stream.Recv()
51+
if err == io.EOF {
52+
return nil
53+
}
54+
if err != nil {
55+
it.error = err
56+
}
57+
return next
58+
}
59+
60+
func (it *BundleIterator) Error() error {
61+
return it.error
62+
}
63+
3164
func (c *Client) GetBundle(ctx context.Context, packageName, channelName, csvName string) (*api.Bundle, error) {
3265
return c.Registry.GetBundle(ctx, &api.GetBundleRequest{PkgName: packageName, ChannelName: channelName, CsvName: csvName})
3366
}
@@ -44,6 +77,14 @@ func (c *Client) GetBundleThatProvides(ctx context.Context, group, version, kind
4477
return c.Registry.GetDefaultBundleThatProvides(ctx, &api.GetDefaultProviderRequest{Group: group, Version: version, Kind: kind})
4578
}
4679

80+
func (c *Client) ListBundles(ctx context.Context) (*BundleIterator, error) {
81+
stream, err := c.Registry.ListBundles(ctx, &api.ListBundlesRequest{})
82+
if err != nil {
83+
return nil, err
84+
}
85+
return NewBundleIterator(stream), nil
86+
}
87+
4788
func (c *Client) Close() error {
4889
if c.Conn == nil {
4990
return nil

pkg/client/client_test.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"errors"
6+
"testing"
7+
8+
"github.com/operator-framework/operator-registry/pkg/api"
9+
"github.com/operator-framework/operator-registry/pkg/api/grpc_health_v1"
10+
11+
"github.com/stretchr/testify/require"
12+
"google.golang.org/grpc"
13+
)
14+
15+
type RegistryClientStub struct {
16+
ListBundlesClient api.Registry_ListBundlesClient
17+
error error
18+
}
19+
20+
func (s *RegistryClientStub) ListPackages(ctx context.Context, in *api.ListPackageRequest, opts ...grpc.CallOption) (api.Registry_ListPackagesClient, error) {
21+
return nil, nil
22+
}
23+
24+
func (s *RegistryClientStub) GetPackage(ctx context.Context, in *api.GetPackageRequest, opts ...grpc.CallOption) (*api.Package, error) {
25+
return nil, nil
26+
}
27+
28+
func (s *RegistryClientStub) GetBundle(ctx context.Context, in *api.GetBundleRequest, opts ...grpc.CallOption) (*api.Bundle, error) {
29+
return nil, nil
30+
}
31+
32+
func (s *RegistryClientStub) GetBundleForChannel(ctx context.Context, in *api.GetBundleInChannelRequest, opts ...grpc.CallOption) (*api.Bundle, error) {
33+
return nil, nil
34+
}
35+
36+
func (s *RegistryClientStub) GetChannelEntriesThatReplace(ctx context.Context, in *api.GetAllReplacementsRequest, opts ...grpc.CallOption) (api.Registry_GetChannelEntriesThatReplaceClient, error) {
37+
return nil, nil
38+
}
39+
40+
func (s *RegistryClientStub) GetBundleThatReplaces(ctx context.Context, in *api.GetReplacementRequest, opts ...grpc.CallOption) (*api.Bundle, error) {
41+
return nil, nil
42+
}
43+
44+
func (s *RegistryClientStub) GetChannelEntriesThatProvide(ctx context.Context, in *api.GetAllProvidersRequest, opts ...grpc.CallOption) (api.Registry_GetChannelEntriesThatProvideClient, error) {
45+
return nil, nil
46+
}
47+
48+
func (s *RegistryClientStub) GetLatestChannelEntriesThatProvide(ctx context.Context, in *api.GetLatestProvidersRequest, opts ...grpc.CallOption) (api.Registry_GetLatestChannelEntriesThatProvideClient, error) {
49+
return nil, nil
50+
}
51+
52+
func (s *RegistryClientStub) GetDefaultBundleThatProvides(ctx context.Context, in *api.GetDefaultProviderRequest, opts ...grpc.CallOption) (*api.Bundle, error) {
53+
return nil, nil
54+
}
55+
56+
func (s *RegistryClientStub) ListBundles(ctx context.Context, in *api.ListBundlesRequest, opts ...grpc.CallOption) (api.Registry_ListBundlesClient, error) {
57+
return s.ListBundlesClient, s.error
58+
}
59+
60+
func (s *RegistryClientStub) Check(ctx context.Context, in *grpc_health_v1.HealthCheckRequest, opts ...grpc.CallOption) (*grpc_health_v1.HealthCheckResponse, error) {
61+
return nil, nil
62+
}
63+
64+
type BundleReceiverStub struct {
65+
Bundle *api.Bundle
66+
error error
67+
grpc.ClientStream
68+
}
69+
70+
func (s *BundleReceiverStub) Recv() (*api.Bundle, error) {
71+
return s.Bundle, s.error
72+
}
73+
74+
func TestListBundlesError(t *testing.T) {
75+
expected := errors.New("test error")
76+
stub := &RegistryClientStub{
77+
error: expected,
78+
}
79+
c := Client{
80+
Registry: stub,
81+
Health: stub,
82+
}
83+
84+
_, actual := c.ListBundles(context.TODO())
85+
require.Equal(t, expected, actual)
86+
}
87+
88+
func TestListBundlesRecvError(t *testing.T) {
89+
expected := errors.New("test error")
90+
rstub := &BundleReceiverStub{
91+
error: expected,
92+
}
93+
cstub := &RegistryClientStub{
94+
ListBundlesClient: rstub,
95+
}
96+
c := Client{
97+
Registry: cstub,
98+
Health: cstub,
99+
}
100+
101+
it, err := c.ListBundles(context.TODO())
102+
require.NoError(t, err)
103+
104+
require.Nil(t, it.Next())
105+
require.Equal(t, expected, it.Error())
106+
}
107+
108+
func TestListBundlesNext(t *testing.T) {
109+
expected := &api.Bundle{CsvName: "test"}
110+
rstub := &BundleReceiverStub{
111+
Bundle: expected,
112+
}
113+
cstub := &RegistryClientStub{
114+
ListBundlesClient: rstub,
115+
}
116+
c := Client{
117+
Registry: cstub,
118+
Health: cstub,
119+
}
120+
121+
it, err := c.ListBundles(context.TODO())
122+
require.NoError(t, err)
123+
124+
actual := it.Next()
125+
require.NoError(t, it.Error())
126+
require.Equal(t, expected, actual)
127+
}

pkg/registry/populator.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,6 @@ func parseDependenciesFile(path string, depFile *DependenciesFile) error {
351351
for _, v := range deps.RawMessage {
352352
// convert map to json
353353
jsonStr, _ := json.Marshal(v)
354-
fmt.Println(string(jsonStr))
355354

356355
// Check dependency type
357356
dep := Dependency{}

pkg/registry/populator_test.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ func TestQuerierForImage(t *testing.T) {
121121
Type: "olm.gvk",
122122
Value: `{"group":"testapi.coreos.com","kind":"testapi","type":"olm.gvk","version":"v1"}`,
123123
},
124+
{
125+
Type: "olm.gvk",
126+
Value: `{"group":"etcd.database.coreos.com","kind":"EtcdCluster","type":"olm.gvk","version":"v1beta2"}`,
127+
},
124128
},
125129
ProvidedApis: []*api.GroupVersionKind{
126130
{Group: "etcd.database.coreos.com", Version: "v1beta2", Kind: "EtcdCluster", Plural: "etcdclusters"},
@@ -403,6 +407,10 @@ func TestQuerierForDependencies(t *testing.T) {
403407
Type: "olm.gvk",
404408
Value: `{"group":"testapi.coreos.com","kind":"testapi","type":"olm.gvk","version":"v1"}`,
405409
},
410+
{
411+
Type: "olm.gvk",
412+
Value: `{"group":"etcd.database.coreos.com","kind":"EtcdCluster","type":"olm.gvk","version":"v1beta2"}`,
413+
},
406414
}
407415

408416
type operatorbundle struct {
@@ -441,6 +449,11 @@ func TestListBundles(t *testing.T) {
441449
store, err := createAndPopulateDB(db)
442450
require.NoError(t, err)
443451

452+
var count int
453+
row := db.QueryRow("SELECT COUNT(*) FROM operatorbundle")
454+
err = row.Scan(&count)
455+
require.NoError(t, err)
456+
444457
expectedDependencies := []*api.Dependency{
445458
{
446459
Type: "olm.package",
@@ -450,15 +463,23 @@ func TestListBundles(t *testing.T) {
450463
Type: "olm.gvk",
451464
Value: `{"group":"testapi.coreos.com","kind":"testapi","type":"olm.gvk","version":"v1"}`,
452465
},
466+
{
467+
Type: "olm.gvk",
468+
Value: `{"group":"etcd.database.coreos.com","kind":"EtcdCluster","type":"olm.gvk","version":"v1beta2"}`,
469+
},
453470
}
454471

455472
dependencies := []*api.Dependency{}
456473
bundles, err := store.ListBundles(context.TODO())
457474
require.NoError(t, err)
458475
for _, b := range bundles {
459-
dep := b.Dependencies
460-
dependencies = append(dependencies, dep...)
476+
for _, d := range b.Dependencies {
477+
if d.GetType() != "" {
478+
dependencies = append(dependencies, d)
479+
}
480+
}
461481
}
482+
require.Equal(t, count, len(bundles))
462483
require.ElementsMatch(t, expectedDependencies, dependencies)
463484
}
464485

@@ -477,7 +498,7 @@ func CheckInvariants(t *testing.T, db *sql.DB) {
477498
func CheckChannelHeadsHaveDescriptions(t *testing.T, db *sql.DB) {
478499
// check channel heads have csv / bundle
479500
rows, err := db.Query(`
480-
select operatorbundle.name,length(operatorbundle.csv),length(operatorbundle.bundle) from operatorbundle
501+
select operatorbundle.name,length(operatorbundle.csv),length(operatorbundle.bundle) from operatorbundle
481502
join channel on channel.head_operatorbundle_name = operatorbundle.name`)
482503
require.NoError(t, err)
483504

@@ -496,7 +517,7 @@ func CheckChannelHeadsHaveDescriptions(t *testing.T, db *sql.DB) {
496517
func CheckBundlesHaveContentsIfNoPath(t *testing.T, db *sql.DB) {
497518
// check that any bundle entry has csv/bundle content unpacked if there is no bundlepath
498519
rows, err := db.Query(`
499-
select name,length(csv),length(bundle) from operatorbundle
520+
select name,length(csv),length(bundle) from operatorbundle
500521
where bundlepath="" or bundlepath=null`)
501522
require.NoError(t, err)
502523

@@ -510,4 +531,4 @@ func CheckBundlesHaveContentsIfNoPath(t *testing.T, db *sql.DB) {
510531
require.NotZero(t, csvlen.Int64, "length of csv for %s should not be zero, it has no bundle path", name.String)
511532
require.NotZero(t, bundlelen.Int64, "length of bundle for %s should not be zero, it has no bundle path", name.String)
512533
}
513-
}
534+
}

pkg/registry/types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ var (
1111
ErrPackageNotInDatabase = errors.New("Package not in database")
1212
)
1313

14+
const (
15+
GVKType = "olm.gvk"
16+
PackageType = "olm.package"
17+
)
18+
1419
// APIKey stores GroupVersionKind for use as map keys
1520
type APIKey struct {
1621
Group string

0 commit comments

Comments
 (0)