Skip to content

Add channel entries to the packagemanifests API #2893

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions pkg/package-server/apis/operators/packagemanifest_types.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package operators

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/operator-framework/api/pkg/lib/version"
operatorv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// PackageManifestList is a list of PackageManifest objects.
@@ -81,6 +80,18 @@ type PackageChannel struct {

// CurrentCSVSpec holds the spec of the current CSV
CurrentCSVDesc CSVDescription

// Entries lists all CSVs in the channel.
Entries []ChannelEntry
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: would refactoring to Entries to ChannelEntries improve readability?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could go either way. We're already in the PackageChannel struct, and none of the other fields have a Channel prefix, so my instinct was just Entries.

I did originally have the struct type ChannelEntry called Entry. I changed from Entry to ChannelEntry in that case because the type is defined at the package level, and it made sense to me for usage of the struct from outside the package to look like operators.ChannelEntry rather than operators.Entry

}

// ChannelEntry defines a member of a package channel.
type ChannelEntry struct {
// Name is the name of the bundle for this entry.
Name string

// Version is the version of the bundle for this entry.
Version string
}

// CSVDescription defines a description of a CSV
15 changes: 13 additions & 2 deletions pkg/package-server/apis/operators/v1/packagemanifest_types.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package v1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/operator-framework/api/pkg/lib/version"
operatorv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// PackageManifestList is a list of PackageManifest objects.
@@ -81,6 +80,18 @@ type PackageChannel struct {

// CurrentCSVSpec holds the spec of the current CSV
CurrentCSVDesc CSVDescription `json:"currentCSVDesc,omitempty"`

// Entries lists all CSVs in the channel, with their upgrade edges.
Entries []ChannelEntry `json:"entries"`
}

// ChannelEntry defines a member of a package channel.
type ChannelEntry struct {
// Name is the name of the bundle for this entry.
Name string `json:"name"`

// Version is the version of the bundle for this entry.
Version string `json:"version,omitempty"`
}

// CSVDescription defines a description of a CSV
34 changes: 34 additions & 0 deletions pkg/package-server/apis/operators/v1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions pkg/package-server/apis/operators/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions pkg/package-server/apis/operators/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

515 changes: 515 additions & 0 deletions pkg/package-server/client/fakes/fake_list_bundles_client.go

Large diffs are not rendered by default.

48 changes: 46 additions & 2 deletions pkg/package-server/client/openapi/zz_generated.openapi.go
59 changes: 51 additions & 8 deletions pkg/package-server/provider/registry.go
Original file line number Diff line number Diff line change
@@ -5,12 +5,14 @@ import (
"encoding/json"
"fmt"
"io"
"sort"
"strings"
"sync"
"time"

"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"

"github.com/blang/semver/v4"
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
"github.com/operator-framework/operator-registry/pkg/api"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/connectivity"
@@ -20,16 +22,15 @@ import (
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/tools/cache"

operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/informers/externalversions"
operatorslisters "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
registrygrpc "github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/grpc"
utillabels "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/util/labels"
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer"
"github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators"
pkglisters "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/listers/operators/internalversion"
"github.com/operator-framework/operator-registry/pkg/api"
)

const (
@@ -277,12 +278,53 @@ func (p *RegistryProvider) refreshCache(ctx context.Context, client *registryCli
"source": key,
})

bundleStream, err := client.ListBundles(ctx, &api.ListBundlesRequest{})
if err != nil {
logger.WithField("err", err.Error()).Warnf("error getting bundle stream")
return nil
}

bundles := map[string]map[string][]operators.ChannelEntry{}
for {
bundle, err := bundleStream.Recv()
if err == io.EOF {
break
}
if err != nil {
logger.WithField("err", err.Error()).Warnf("error getting bundle data")
break
}
if _, ok := bundles[bundle.PackageName]; !ok {
bundles[bundle.PackageName] = map[string][]operators.ChannelEntry{}
}
bundles[bundle.PackageName][bundle.ChannelName] = append(bundles[bundle.PackageName][bundle.ChannelName], operators.ChannelEntry{
Name: bundle.CsvName,
Version: bundle.Version,
})
}

stream, err := client.ListPackages(ctx, &api.ListPackageRequest{})
if err != nil {
logger.WithField("err", err.Error()).Warnf("error getting stream")
logger.WithField("err", err.Error()).Warnf("error getting package stream")
return nil
}

for pkgName := range bundles {
for chName := range bundles[pkgName] {
sort.Slice(bundles[pkgName][chName], func(i, j int) bool {
iV, err := semver.Parse(bundles[pkgName][chName][i].Version)
if err != nil {
iV = semver.Version{}
}
jV, err := semver.Parse(bundles[pkgName][chName][j].Version)
if err != nil {
jV = semver.Version{}
}
return iV.GT(jV)
})
}
}

var (
added = map[string]struct{}{}
mu sync.Mutex
@@ -294,7 +336,7 @@ func (p *RegistryProvider) refreshCache(ctx context.Context, client *registryCli
break
}
if err != nil {
logger.WithField("err", err.Error()).Warnf("error getting data")
logger.WithField("err", err.Error()).Warnf("error getting package name data")
break
}

@@ -307,7 +349,7 @@ func (p *RegistryProvider) refreshCache(ctx context.Context, client *registryCli
return
}

newPkg, err := newPackageManifest(ctx, logger, pkg, client)
newPkg, err := newPackageManifest(ctx, logger, pkg, client, bundles[pkg.GetName()])
if err != nil {
logger.WithField("err", err.Error()).Warnf("eliding package: error converting to packagemanifest")
return
@@ -454,7 +496,7 @@ func (p *RegistryProvider) List(namespace string, selector labels.Selector) (*op
return pkgList, nil
}

func newPackageManifest(ctx context.Context, logger *logrus.Entry, pkg *api.Package, client *registryClient) (*operators.PackageManifest, error) {
func newPackageManifest(ctx context.Context, logger *logrus.Entry, pkg *api.Package, client *registryClient, entriesByChannel map[string][]operators.ChannelEntry) (*operators.PackageManifest, error) {
pkgChannels := pkg.GetChannels()
catsrc := client.catsrc
manifest := &operators.PackageManifest{
@@ -503,6 +545,7 @@ func newPackageManifest(ctx context.Context, logger *logrus.Entry, pkg *api.Pack
Name: pkgChannel.GetName(),
CurrentCSV: csv.GetName(),
CurrentCSVDesc: operators.CreateCSVDescription(&csv, bundle.GetCsvJson()),
Entries: entriesByChannel[pkgChannel.GetName()],
})

if manifest.Status.DefaultChannel != "" && pkgChannel.GetName() == manifest.Status.DefaultChannel || !providerSet {
72 changes: 68 additions & 4 deletions pkg/package-server/provider/registry_test.go

Large diffs are not rendered by default.

20 changes: 18 additions & 2 deletions test/e2e/packagemanifest_e2e_test.go
Original file line number Diff line number Diff line change
@@ -8,12 +8,12 @@ import (
"github.com/blang/semver/v4"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
opver "github.com/operator-framework/api/pkg/lib/version"
"github.com/operator-framework/api/pkg/operators/v1alpha1"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/rest"

opver "github.com/operator-framework/api/pkg/lib/version"
"github.com/operator-framework/api/pkg/operators/v1alpha1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry"
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
@@ -140,11 +140,27 @@ var _ = Describe("Package Manifest API lists available Operators from Catalog So
Name: alphaChannel,
CurrentCSV: packageAlpha,
CurrentCSVDesc: packagev1.CreateCSVDescription(&csvAlpha, string(csvAlphaJSON)),
Entries: []packagev1.ChannelEntry{
{
Name: csvAlpha.Name,
Version: csvAlpha.Spec.Version.String(),
},
{
Name: csv.Name,
Version: csv.Spec.Version.String(),
},
},
},
{
Name: stableChannel,
CurrentCSV: packageStable,
CurrentCSVDesc: packagev1.CreateCSVDescription(&csv, string(csvJSON)),
Entries: []packagev1.ChannelEntry{
{
Name: csv.Name,
Version: csv.Spec.Version.String(),
},
},
},
},
DefaultChannel: stableChannel,