Skip to content

Commit 869cc2f

Browse files
committed
feat(packageserver): support label queries and copy CSV labels onto the
packagemanifest
1 parent f85c7ba commit 869cc2f

File tree

5 files changed

+157
-49
lines changed

5 files changed

+157
-49
lines changed
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package provider
22

3-
import "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators"
3+
import (
4+
"github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators"
5+
"k8s.io/apimachinery/pkg/labels"
6+
)
47

58
type PackageManifestProvider interface {
69
Get(namespace, name string) (*operators.PackageManifest, error)
7-
List(namespace string) (*operators.PackageManifestList, error)
10+
List(namespace string, selector labels.Selector) (*operators.PackageManifestList, error)
811
}

pkg/package-server/provider/registry.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ func (p *RegistryProvider) Get(namespace, name string) (*operators.PackageManife
370370
"namespace": namespace,
371371
})
372372

373-
pkgs, err := p.List(namespace)
373+
pkgs, err := p.List(namespace, labels.Everything())
374374
if err != nil {
375375
return nil, fmt.Errorf("could not list packages in namespace %s", namespace)
376376
}
@@ -385,7 +385,7 @@ func (p *RegistryProvider) Get(namespace, name string) (*operators.PackageManife
385385
return nil, nil
386386
}
387387

388-
func (p *RegistryProvider) List(namespace string) (*operators.PackageManifestList, error) {
388+
func (p *RegistryProvider) List(namespace string, selector labels.Selector) (*operators.PackageManifestList, error) {
389389
var pkgs []*operators.PackageManifest
390390
if namespace == metav1.NamespaceAll {
391391
all, err := p.pkgLister.List(labels.Everything())
@@ -394,14 +394,14 @@ func (p *RegistryProvider) List(namespace string) (*operators.PackageManifestLis
394394
}
395395
pkgs = append(pkgs, all...)
396396
} else {
397-
nsPkgs, err := p.pkgLister.PackageManifests(namespace).List(labels.Everything())
397+
nsPkgs, err := p.pkgLister.PackageManifests(namespace).List(selector)
398398
if err != nil {
399399
return nil, err
400400
}
401401
pkgs = append(pkgs, nsPkgs...)
402402

403403
if namespace != p.globalNamespace {
404-
globalPkgs, err := p.pkgLister.PackageManifests(p.globalNamespace).List(labels.Everything())
404+
globalPkgs, err := p.pkgLister.PackageManifests(p.globalNamespace).List(selector)
405405
if err != nil {
406406
return nil, err
407407
}
@@ -464,6 +464,11 @@ func newPackageManifest(ctx context.Context, logger *logrus.Entry, pkg *api.Pack
464464
defaultElided = defaultElided || pkgChannel.Name == manifest.Status.DefaultChannel
465465
continue
466466
}
467+
manifestLabels := manifest.GetLabels()
468+
for k, v := range csv.GetLabels() {
469+
manifestLabels[k] = v
470+
}
471+
manifest.SetLabels(manifest.GetLabels())
467472
manifest.Status.Channels = append(manifest.Status.Channels, operators.PackageChannel{
468473
Name: pkgChannel.GetName(),
469474
CurrentCSV: csv.GetName(),

pkg/package-server/provider/registry_test.go

Lines changed: 68 additions & 6 deletions
Large diffs are not rendered by default.

pkg/package-server/storage/reststorage.go

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ package storage
22

33
import (
44
"context"
5-
"fmt"
65

76
k8serrors "k8s.io/apimachinery/pkg/api/errors"
87
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
98
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10-
"k8s.io/apimachinery/pkg/fields"
119
"k8s.io/apimachinery/pkg/labels"
1210
"k8s.io/apimachinery/pkg/runtime"
1311
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -68,24 +66,12 @@ func (m *PackageManifestStorage) List(ctx context.Context, options *metainternal
6866
labelSelector = options.LabelSelector
6967
}
7068

71-
name, err := nameFor(options.FieldSelector)
72-
if err != nil {
73-
return nil, err
74-
}
75-
76-
res, err := m.prov.List(namespace)
69+
res, err := m.prov.List(namespace, labelSelector)
7770
if err != nil {
7871
return nil, k8serrors.NewInternalError(err)
7972
}
8073

81-
// Filter by label selector
82-
filtered := []operators.PackageManifest{}
83-
for _, manifest := range res.Items {
84-
if matches(manifest, name, labelSelector) {
85-
filtered = append(filtered, manifest)
86-
}
87-
}
88-
// Strip logo icons
74+
filtered := res.Items
8975
for i := range filtered {
9076
for j := range filtered[i].Status.Channels {
9177
filtered[i].Status.Channels[j].CurrentCSVDesc.Icon = []operators.Icon{}
@@ -115,23 +101,3 @@ func (m *PackageManifestStorage) Get(ctx context.Context, name string, opts *met
115101
func (m *PackageManifestStorage) NamespaceScoped() bool {
116102
return true
117103
}
118-
119-
func nameFor(fs fields.Selector) (string, error) {
120-
if fs == nil {
121-
fs = fields.Everything()
122-
}
123-
name := ""
124-
if value, found := fs.RequiresExactMatch("metadata.name"); found {
125-
name = value
126-
} else if !fs.Empty() {
127-
return "", fmt.Errorf("field label not supported: %s", fs.Requirements()[0].Field)
128-
}
129-
return name, nil
130-
}
131-
132-
func matches(pm operators.PackageManifest, name string, ls labels.Selector) bool {
133-
if name == "" {
134-
name = pm.GetName()
135-
}
136-
return ls.Matches(labels.Set(pm.GetLabels())) && pm.GetName() == name
137-
}

test/e2e/packagemanifest_e2e_test.go

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ func TestPackageManifestLoading(t *testing.T) {
6666
catalogSourceName := genName("mock-ocs")
6767
namedStrategy := newNginxInstallStrategy(genName("dep-"), nil, nil)
6868
csv := newCSV(packageStable, testNamespace, "", semver.MustParse("0.1.0"), []apiextensions.CustomResourceDefinition{crd}, nil, namedStrategy)
69-
7069
c := newKubeClient(t)
7170
crc := newCRClient(t)
7271
pmc := newPMClient(t)
@@ -115,3 +114,76 @@ func TestPackageManifestLoading(t *testing.T) {
115114
require.NotNil(t, pmList.ListMeta, "package manifest list metadata empty")
116115
require.NotNil(t, pmList.Items)
117116
}
117+
118+
func TestPackageManifestLoading(t *testing.T) {
119+
defer cleaner.NotifyTestComplete(t, true)
120+
121+
// create a simple catalogsource
122+
packageName := genName("nginx")
123+
stableChannel := "stable"
124+
packageStable := packageName + "-stable"
125+
manifests := []registry.PackageManifest{
126+
{
127+
PackageName: packageName,
128+
Channels: []registry.PackageChannel{
129+
{Name: stableChannel, CurrentCSVName: packageStable},
130+
},
131+
DefaultChannelName: stableChannel,
132+
},
133+
}
134+
135+
crdPlural := genName("ins")
136+
crd := newCRD(crdPlural)
137+
catalogSourceName := genName("mock-ocs")
138+
namedStrategy := newNginxInstallStrategy(genName("dep-"), nil, nil)
139+
csv := newCSV(packageStable, testNamespace, "", semver.MustParse("0.1.0"), []apiextensions.CustomResourceDefinition{crd}, nil, namedStrategy)
140+
csv.SetLabels(map[string]string{"projected": "label"})
141+
c := newKubeClient(t)
142+
crc := newCRClient(t)
143+
pmc := newPMClient(t)
144+
145+
expectedStatus := packagev1.PackageManifestStatus{
146+
CatalogSource: catalogSourceName,
147+
CatalogSourceNamespace: testNamespace,
148+
PackageName: packageName,
149+
Channels: []packagev1.PackageChannel{
150+
{
151+
Name: stableChannel,
152+
CurrentCSV: packageStable,
153+
CurrentCSVDesc: packagev1.CreateCSVDescription(&csv),
154+
},
155+
},
156+
DefaultChannel: stableChannel,
157+
}
158+
159+
// Wait for package-server to be ready
160+
err := wait.Poll(pollInterval, 1*time.Minute, func() (bool, error) {
161+
t.Logf("Polling package-server...")
162+
_, err := pmc.OperatorsV1().PackageManifests(testNamespace).List(metav1.ListOptions{})
163+
if err == nil {
164+
return true, nil
165+
}
166+
return false, nil
167+
})
168+
require.NoError(t, err, "package-server not available")
169+
170+
_, cleanupCatalogSource := createInternalCatalogSource(t, c, crc, catalogSourceName, testNamespace, manifests, []apiextensions.CustomResourceDefinition{crd}, []v1alpha1.ClusterServiceVersion{csv})
171+
require.NoError(t, err)
172+
defer cleanupCatalogSource()
173+
174+
_, err = fetchCatalogSource(t, crc, catalogSourceName, testNamespace, catalogSourceRegistryPodSynced)
175+
require.NoError(t, err)
176+
177+
pm, err := fetchPackageManifest(t, pmc, testNamespace, packageName, packageManifestHasStatus)
178+
require.NoError(t, err, "error getting package manifest")
179+
require.NotNil(t, pm)
180+
require.Equal(t, packageName, pm.GetName())
181+
require.Equal(t, expectedStatus, pm.Status)
182+
require.Contains(t, pm.GetLabels(), map[string]string{"projected": "label"})
183+
184+
// Filter PackageManifestList and ensure it has the correct items
185+
pmList, err := pmc.OperatorsV1().PackageManifests(testNamespace).List(metav1.ListOptions{LabelSelector: "projected=label"})
186+
require.NoError(t, err, "could not access package manifests list meta")
187+
require.NotNil(t, pmList.ListMeta, "package manifest list metadata empty")
188+
require.NotNil(t, pmList.Items)
189+
}

0 commit comments

Comments
 (0)