Skip to content

Commit 6900307

Browse files
Merge pull request #1220 from ecordell/packagserver-labels
feat(packageserver): support label queries and copy CSV labels onto the package
2 parents ffb7589 + a5fa4a4 commit 6900307

File tree

8 files changed

+259
-67
lines changed

8 files changed

+259
-67
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/labels.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package provider
2+
3+
import "strings"
4+
5+
const (
6+
OsLabelPrefix = "operatorframework.io/os"
7+
ArchLabelPrefix = "operatorframework.io/arch"
8+
DefaultOsLabel = "operatorframework.io/os.linux"
9+
DefaultArchLabel = "operatorframework.io/arch.amd64"
10+
Supported = "supported"
11+
)
12+
13+
func setDefaultOsArchLabels(labels map[string]string) {
14+
needsOsLabel := true
15+
needsArchLabel := true
16+
for k := range labels {
17+
if strings.HasPrefix(k, OsLabelPrefix) {
18+
needsOsLabel = false
19+
}
20+
if strings.HasPrefix(k, ArchLabelPrefix) {
21+
needsArchLabel = false
22+
}
23+
}
24+
if needsOsLabel {
25+
labels[DefaultOsLabel] = Supported
26+
}
27+
if needsArchLabel {
28+
labels[DefaultArchLabel] = Supported
29+
}
30+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package provider
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestSetDefaultOsArchLabels(t *testing.T) {
10+
type args struct {
11+
labels map[string]string
12+
}
13+
tests := []struct {
14+
name string
15+
args args
16+
expected map[string]string
17+
}{
18+
{
19+
name: "NoneSet",
20+
args: args{labels: map[string]string{}},
21+
expected: map[string]string{
22+
DefaultArchLabel: Supported,
23+
DefaultOsLabel: Supported,
24+
},
25+
},
26+
{
27+
name: "OthersPreserved",
28+
args: args{labels: map[string]string{"other": "label"}},
29+
expected: map[string]string{
30+
"other": "label",
31+
DefaultArchLabel: Supported,
32+
DefaultOsLabel: Supported,
33+
},
34+
},
35+
{
36+
name: "OsSet",
37+
args: args{labels: map[string]string{OsLabelPrefix + ".windows": Supported}},
38+
expected: map[string]string{
39+
DefaultArchLabel: Supported,
40+
OsLabelPrefix + ".windows": Supported,
41+
},
42+
},
43+
{
44+
name: "ArchSet",
45+
args: args{labels: map[string]string{ArchLabelPrefix + ".arm": Supported}},
46+
expected: map[string]string{
47+
ArchLabelPrefix + ".arm": Supported,
48+
DefaultOsLabel: Supported,
49+
},
50+
},
51+
}
52+
for _, tt := range tests {
53+
t.Run(tt.name, func(t *testing.T) {
54+
labels := tt.args.labels
55+
setDefaultOsArchLabels(labels)
56+
require.Equal(t, tt.expected, labels)
57+
})
58+
}
59+
}

pkg/package-server/provider/registry.go

Lines changed: 14 additions & 5 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
}
@@ -448,6 +448,7 @@ func newPackageManifest(ctx context.Context, logger *logrus.Entry, pkg *api.Pack
448448
var (
449449
providerSet bool
450450
defaultElided bool
451+
defaultCsv *operatorsv1alpha1.ClusterServiceVersion
451452
)
452453
for _, pkgChannel := range pkgChannels {
453454
bundle, err := client.GetBundleForChannel(ctx, &api.GetBundleInChannelRequest{PkgName: pkg.GetName(), ChannelName: pkgChannel.GetName()})
@@ -464,6 +465,9 @@ func newPackageManifest(ctx context.Context, logger *logrus.Entry, pkg *api.Pack
464465
defaultElided = defaultElided || pkgChannel.Name == manifest.Status.DefaultChannel
465466
continue
466467
}
468+
if defaultCsv == nil || pkgChannel.GetName() == manifest.Status.DefaultChannel {
469+
defaultCsv = &csv
470+
}
467471
manifest.Status.Channels = append(manifest.Status.Channels, operators.PackageChannel{
468472
Name: pkgChannel.GetName(),
469473
CurrentCSV: csv.GetName(),
@@ -489,6 +493,11 @@ func newPackageManifest(ctx context.Context, logger *logrus.Entry, pkg *api.Pack
489493
logger.Warn("default channel elided, setting as first in packagemanifest")
490494
manifest.Status.DefaultChannel = manifest.Status.Channels[0].Name
491495
}
492-
496+
manifestLabels := manifest.GetLabels()
497+
for k, v := range defaultCsv.GetLabels() {
498+
manifestLabels[k] = v
499+
}
500+
setDefaultOsArchLabels(manifestLabels)
501+
manifest.SetLabels(manifestLabels)
493502
return manifest, nil
494503
}

pkg/package-server/provider/registry_test.go

Lines changed: 137 additions & 51 deletions
Large diffs are not rendered by default.

pkg/package-server/storage/reststorage.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import (
44
"context"
55
"fmt"
66

7+
"k8s.io/apimachinery/pkg/fields"
8+
79
k8serrors "k8s.io/apimachinery/pkg/api/errors"
810
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
911
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10-
"k8s.io/apimachinery/pkg/fields"
1112
"k8s.io/apimachinery/pkg/labels"
1213
"k8s.io/apimachinery/pkg/runtime"
1314
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -73,19 +74,18 @@ func (m *PackageManifestStorage) List(ctx context.Context, options *metainternal
7374
return nil, err
7475
}
7576

76-
res, err := m.prov.List(namespace)
77+
res, err := m.prov.List(namespace, labelSelector)
7778
if err != nil {
7879
return nil, k8serrors.NewInternalError(err)
7980
}
8081

81-
// Filter by label selector
8282
filtered := []operators.PackageManifest{}
8383
for _, manifest := range res.Items {
84-
if matches(manifest, name, labelSelector) {
84+
if matches(manifest, name) {
8585
filtered = append(filtered, manifest)
8686
}
8787
}
88-
// Strip logo icons
88+
8989
for i := range filtered {
9090
for j := range filtered[i].Status.Channels {
9191
filtered[i].Status.Channels[j].CurrentCSVDesc.Icon = []operators.Icon{}
@@ -129,9 +129,9 @@ func nameFor(fs fields.Selector) (string, error) {
129129
return name, nil
130130
}
131131

132-
func matches(pm operators.PackageManifest, name string, ls labels.Selector) bool {
132+
func matches(pm operators.PackageManifest, name string) bool {
133133
if name == "" {
134134
name = pm.GetName()
135135
}
136-
return ls.Matches(labels.Set(pm.GetLabels())) && pm.GetName() == name
136+
return pm.GetName() == name
137137
}

pkg/package-server/storage/subresources_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"net/http/httptest"
77
"testing"
88

9+
"k8s.io/apimachinery/pkg/labels"
10+
911
"github.com/stretchr/testify/require"
1012

1113
"github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators"
@@ -25,7 +27,7 @@ func (p *fakeProvider) Get(namespace, name string) (*operators.PackageManifest,
2527
return p.packages[0], nil
2628
}
2729

28-
func (p *fakeProvider) List(namespace string) (*operators.PackageManifestList, error) {
30+
func (p *fakeProvider) List(namespace string, selector labels.Selector) (*operators.PackageManifestList, error) {
2931
return &operators.PackageManifestList{}, nil
3032
}
3133

test/e2e/packagemanifest_e2e_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ 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-
69+
csv.SetLabels(map[string]string{"projected": "label"})
7070
c := newKubeClient(t)
7171
crc := newCRClient(t)
7272
pmc := newPMClient(t)
@@ -108,6 +108,9 @@ func TestPackageManifestLoading(t *testing.T) {
108108
require.NotNil(t, pm)
109109
require.Equal(t, packageName, pm.GetName())
110110
require.Equal(t, expectedStatus, pm.Status)
111+
require.Equal(t, "label", pm.GetLabels()["projected"])
112+
require.Equal(t, "supported", pm.GetLabels()["operatorframework.io/arch.amd64"])
113+
require.Equal(t, "supported", pm.GetLabels()["operatorframework.io/os.linux"])
111114

112115
// Get a PackageManifestList and ensure it has the correct items
113116
pmList, err := pmc.OperatorsV1().PackageManifests(testNamespace).List(metav1.ListOptions{})

0 commit comments

Comments
 (0)