Skip to content

Commit 20fac5f

Browse files
Merge pull request #1322 from exdx/fix/duplicate-packages
Bug 1799463: Duplicate packages in packageserver APIService response
2 parents e2afc21 + 7b4b648 commit 20fac5f

File tree

2 files changed

+312
-1
lines changed

2 files changed

+312
-1
lines changed

pkg/package-server/provider/registry.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ func (p *RegistryProvider) Get(namespace, name string) (*operators.PackageManife
412412
func (p *RegistryProvider) List(namespace string, selector labels.Selector) (*operators.PackageManifestList, error) {
413413
var pkgs []*operators.PackageManifest
414414
if namespace == metav1.NamespaceAll {
415-
all, err := p.pkgLister.List(labels.Everything())
415+
all, err := p.pkgLister.List(selector)
416416
if err != nil {
417417
return nil, err
418418
}

pkg/package-server/provider/registry_test.go

Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"encoding/json"
99
"fmt"
1010
"io"
11+
"k8s.io/apimachinery/pkg/selection"
1112
"net"
1213
"os"
1314
"path/filepath"
@@ -1076,6 +1077,316 @@ func TestRegistryProviderList(t *testing.T) {
10761077
}
10771078
}
10781079

1080+
type LabelReq struct {
1081+
key string
1082+
op selection.Operator
1083+
strValues []string
1084+
}
1085+
1086+
func TestRegistryProviderListLabels(t *testing.T) {
1087+
tests := []struct {
1088+
name string
1089+
globalNS string
1090+
labelReq *LabelReq
1091+
registryClients []*registryClient
1092+
requestNamespace string
1093+
expectedErr string
1094+
expected *operators.PackageManifestList
1095+
}{
1096+
{
1097+
name: "PackagesFound/LabelsSupported/SingleNS",
1098+
globalNS: "ns",
1099+
labelReq: &LabelReq{
1100+
key: "catalog",
1101+
op: selection.Exists,
1102+
},
1103+
registryClients: []*registryClient{
1104+
newTestRegistryClient(t, withRegistryServiceStatus(catalogSource("cool-operators", "ns"), "grpc", "cool-operators", "ns", port, metav1.NewTime(time.Now()))),
1105+
},
1106+
requestNamespace: "ns",
1107+
expectedErr: "",
1108+
expected: &operators.PackageManifestList{Items: []operators.PackageManifest{
1109+
{
1110+
ObjectMeta: metav1.ObjectMeta{
1111+
Name: "prometheus",
1112+
Namespace: "ns",
1113+
Labels: labels.Set{
1114+
"catalog": "cool-operators",
1115+
"catalog-namespace": "ns",
1116+
"provider": "Red Hat",
1117+
"provider-url": "",
1118+
"operatorframework.io/arch.amd64": "supported",
1119+
"operatorframework.io/os.linux": "supported",
1120+
},
1121+
},
1122+
Status: operators.PackageManifestStatus{
1123+
CatalogSource: "cool-operators",
1124+
CatalogSourceNamespace: "ns",
1125+
PackageName: "prometheus",
1126+
Provider: operators.AppLink{
1127+
Name: "Red Hat",
1128+
},
1129+
DefaultChannel: "preview",
1130+
Channels: []operators.PackageChannel{
1131+
{
1132+
Name: "preview",
1133+
CurrentCSV: "prometheusoperator.0.22.2",
1134+
CurrentCSVDesc: func() operators.CSVDescription {
1135+
csv := operatorsv1alpha1.ClusterServiceVersion{}
1136+
require.NoError(t, json.Unmarshal([]byte(prometheusCSVJSON), &csv))
1137+
return operators.CreateCSVDescription(&csv)
1138+
}(),
1139+
},
1140+
},
1141+
},
1142+
},
1143+
{
1144+
ObjectMeta: metav1.ObjectMeta{
1145+
Name: "etcd",
1146+
Namespace: "ns",
1147+
Labels: labels.Set{
1148+
"catalog": "cool-operators",
1149+
"catalog-namespace": "ns",
1150+
"provider": "CoreOS, Inc",
1151+
"provider-url": "",
1152+
"operatorframework.io/arch.amd64": "supported",
1153+
"operatorframework.io/os.linux": "supported",
1154+
},
1155+
},
1156+
Status: operators.PackageManifestStatus{
1157+
CatalogSource: "cool-operators",
1158+
CatalogSourceNamespace: "ns",
1159+
PackageName: "etcd",
1160+
Provider: operators.AppLink{
1161+
Name: "CoreOS, Inc",
1162+
},
1163+
DefaultChannel: "alpha",
1164+
Channels: []operators.PackageChannel{
1165+
{
1166+
Name: "alpha",
1167+
CurrentCSV: "etcdoperator.v0.9.2",
1168+
CurrentCSVDesc: func() operators.CSVDescription {
1169+
csv := operatorsv1alpha1.ClusterServiceVersion{}
1170+
require.NoError(t, json.Unmarshal([]byte(etcdCSVJSON), &csv))
1171+
return operators.CreateCSVDescription(&csv)
1172+
}(),
1173+
},
1174+
},
1175+
},
1176+
},
1177+
}},
1178+
},
1179+
{
1180+
name: "PackagesFound/LabelsSupported/GlobalNS",
1181+
globalNS: "ns",
1182+
labelReq: &LabelReq{
1183+
key: "catalog",
1184+
op: selection.Exists,
1185+
},
1186+
registryClients: []*registryClient{
1187+
newTestRegistryClient(t, withRegistryServiceStatus(catalogSource("cool-operators", "ns"), "grpc", "cool-operators", "ns", port, metav1.NewTime(time.Now()))),
1188+
},
1189+
requestNamespace: "",
1190+
expectedErr: "",
1191+
expected: &operators.PackageManifestList{Items: []operators.PackageManifest{
1192+
{
1193+
ObjectMeta: metav1.ObjectMeta{
1194+
Name: "prometheus",
1195+
Namespace: "ns",
1196+
Labels: labels.Set{
1197+
"catalog": "cool-operators",
1198+
"catalog-namespace": "ns",
1199+
"provider": "Red Hat",
1200+
"provider-url": "",
1201+
"operatorframework.io/arch.amd64": "supported",
1202+
"operatorframework.io/os.linux": "supported",
1203+
},
1204+
},
1205+
Status: operators.PackageManifestStatus{
1206+
CatalogSource: "cool-operators",
1207+
CatalogSourceNamespace: "ns",
1208+
PackageName: "prometheus",
1209+
Provider: operators.AppLink{
1210+
Name: "Red Hat",
1211+
},
1212+
DefaultChannel: "preview",
1213+
Channels: []operators.PackageChannel{
1214+
{
1215+
Name: "preview",
1216+
CurrentCSV: "prometheusoperator.0.22.2",
1217+
CurrentCSVDesc: func() operators.CSVDescription {
1218+
csv := operatorsv1alpha1.ClusterServiceVersion{}
1219+
require.NoError(t, json.Unmarshal([]byte(prometheusCSVJSON), &csv))
1220+
return operators.CreateCSVDescription(&csv)
1221+
}(),
1222+
},
1223+
},
1224+
},
1225+
},
1226+
{
1227+
ObjectMeta: metav1.ObjectMeta{
1228+
Name: "etcd",
1229+
Namespace: "ns",
1230+
Labels: labels.Set{
1231+
"catalog": "cool-operators",
1232+
"catalog-namespace": "ns",
1233+
"provider": "CoreOS, Inc",
1234+
"provider-url": "",
1235+
"operatorframework.io/arch.amd64": "supported",
1236+
"operatorframework.io/os.linux": "supported",
1237+
},
1238+
},
1239+
Status: operators.PackageManifestStatus{
1240+
CatalogSource: "cool-operators",
1241+
CatalogSourceNamespace: "ns",
1242+
PackageName: "etcd",
1243+
Provider: operators.AppLink{
1244+
Name: "CoreOS, Inc",
1245+
},
1246+
DefaultChannel: "alpha",
1247+
Channels: []operators.PackageChannel{
1248+
{
1249+
Name: "alpha",
1250+
CurrentCSV: "etcdoperator.v0.9.2",
1251+
CurrentCSVDesc: func() operators.CSVDescription {
1252+
csv := operatorsv1alpha1.ClusterServiceVersion{}
1253+
require.NoError(t, json.Unmarshal([]byte(etcdCSVJSON), &csv))
1254+
return operators.CreateCSVDescription(&csv)
1255+
}(),
1256+
},
1257+
},
1258+
},
1259+
},
1260+
}},
1261+
},
1262+
{
1263+
name: "PackagesNotFound/LabelsNotSupported/GlobalNS",
1264+
globalNS: "",
1265+
labelReq: &LabelReq{
1266+
key: "catalog",
1267+
op: selection.DoesNotExist,
1268+
},
1269+
registryClients: []*registryClient{
1270+
newTestRegistryClient(t, withRegistryServiceStatus(catalogSource("cool-operators", ""), "grpc", "cool-operators", "ns", port, metav1.NewTime(time.Now()))),
1271+
},
1272+
requestNamespace: "",
1273+
expectedErr: "",
1274+
expected: &operators.PackageManifestList{Items: []operators.PackageManifest{}},
1275+
},
1276+
{
1277+
name: "PackagesFound/LabelsNotProvided/GlobalNS",
1278+
globalNS: "",
1279+
registryClients: []*registryClient{
1280+
newTestRegistryClient(t, withRegistryServiceStatus(catalogSource("cool-operators", "ns"), "grpc", "cool-operators", "ns", port, metav1.NewTime(time.Now()))),
1281+
},
1282+
requestNamespace: "",
1283+
expectedErr: "",
1284+
expected: &operators.PackageManifestList{Items: []operators.PackageManifest{
1285+
{
1286+
ObjectMeta: metav1.ObjectMeta{
1287+
Name: "prometheus",
1288+
Namespace: "ns",
1289+
Labels: labels.Set{
1290+
"catalog": "cool-operators",
1291+
"catalog-namespace": "ns",
1292+
"provider": "Red Hat",
1293+
"provider-url": "",
1294+
"operatorframework.io/arch.amd64": "supported",
1295+
"operatorframework.io/os.linux": "supported",
1296+
},
1297+
},
1298+
Status: operators.PackageManifestStatus{
1299+
CatalogSource: "cool-operators",
1300+
CatalogSourceNamespace: "ns",
1301+
PackageName: "prometheus",
1302+
Provider: operators.AppLink{
1303+
Name: "Red Hat",
1304+
},
1305+
DefaultChannel: "preview",
1306+
Channels: []operators.PackageChannel{
1307+
{
1308+
Name: "preview",
1309+
CurrentCSV: "prometheusoperator.0.22.2",
1310+
CurrentCSVDesc: func() operators.CSVDescription {
1311+
csv := operatorsv1alpha1.ClusterServiceVersion{}
1312+
require.NoError(t, json.Unmarshal([]byte(prometheusCSVJSON), &csv))
1313+
return operators.CreateCSVDescription(&csv)
1314+
}(),
1315+
},
1316+
},
1317+
},
1318+
},
1319+
{
1320+
ObjectMeta: metav1.ObjectMeta{
1321+
Name: "etcd",
1322+
Namespace: "ns",
1323+
Labels: labels.Set{
1324+
"catalog": "cool-operators",
1325+
"catalog-namespace": "ns",
1326+
"provider": "CoreOS, Inc",
1327+
"provider-url": "",
1328+
"operatorframework.io/arch.amd64": "supported",
1329+
"operatorframework.io/os.linux": "supported",
1330+
},
1331+
},
1332+
Status: operators.PackageManifestStatus{
1333+
CatalogSource: "cool-operators",
1334+
CatalogSourceNamespace: "ns",
1335+
PackageName: "etcd",
1336+
Provider: operators.AppLink{
1337+
Name: "CoreOS, Inc",
1338+
},
1339+
DefaultChannel: "alpha",
1340+
Channels: []operators.PackageChannel{
1341+
{
1342+
Name: "alpha",
1343+
CurrentCSV: "etcdoperator.v0.9.2",
1344+
CurrentCSVDesc: func() operators.CSVDescription {
1345+
csv := operatorsv1alpha1.ClusterServiceVersion{}
1346+
require.NoError(t, json.Unmarshal([]byte(etcdCSVJSON), &csv))
1347+
return operators.CreateCSVDescription(&csv)
1348+
}(),
1349+
},
1350+
},
1351+
},
1352+
},
1353+
}},
1354+
},
1355+
}
1356+
1357+
for _, test := range tests {
1358+
t.Run(test.name, func(t *testing.T) {
1359+
ctx, cancel := context.WithCancel(context.TODO())
1360+
defer cancel()
1361+
1362+
lab := labels.NewSelector()
1363+
if test.labelReq != nil {
1364+
req, err := labels.NewRequirement(test.labelReq.key, test.labelReq.op, test.labelReq.strValues)
1365+
require.NoError(t, err)
1366+
lab = lab.Add(*req)
1367+
}
1368+
1369+
provider, err := NewFakeRegistryProvider(ctx, nil, nil, test.globalNS)
1370+
require.NoError(t, err)
1371+
1372+
for _, c := range test.registryClients {
1373+
require.NoError(t, provider.refreshCache(ctx, c))
1374+
}
1375+
1376+
packageManifestList, err := provider.List(test.requestNamespace, lab)
1377+
if test.expectedErr != "" {
1378+
require.NotNil(t, err)
1379+
require.Equal(t, test.expectedErr, err.Error())
1380+
} else {
1381+
require.Nil(t, err)
1382+
}
1383+
1384+
require.Equal(t, len(test.expected.Items), len(packageManifestList.Items))
1385+
require.ElementsMatch(t, test.expected.Items, packageManifestList.Items)
1386+
})
1387+
}
1388+
}
1389+
10791390
func newTestRegistryClient(t *testing.T, catsrc *operatorsv1alpha1.CatalogSource) *registryClient {
10801391
conn, err := grpc.Dial(address+catsrc.Status.RegistryServiceStatus.Port, grpc.WithInsecure())
10811392
require.NoError(t, err, "could not set up test grpc connection")

0 commit comments

Comments
 (0)