Skip to content

Commit f0840a9

Browse files
authored
clustercatalog content discovery for packages and bundle versions (#239)
* clustercatalog content discovery for packages and bundle versions Signed-off-by: Ankita Thomas <[email protected]> * linter fixes Signed-off-by: Ankita Thomas <[email protected]> --------- Signed-off-by: Ankita Thomas <[email protected]>
1 parent 4b54083 commit f0840a9

File tree

10 files changed

+693
-1
lines changed

10 files changed

+693
-1
lines changed

go.mod

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ require (
5757
github.com/felixge/httpsnoop v1.0.4 // indirect
5858
github.com/fsnotify/fsnotify v1.8.0 // indirect
5959
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
60+
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
61+
github.com/go-git/go-billy/v5 v5.6.1 // indirect
62+
github.com/go-git/go-git/v5 v5.13.1 // indirect
6063
github.com/go-logr/logr v1.4.2 // indirect
6164
github.com/go-logr/stdr v1.2.2 // indirect
6265
github.com/go-openapi/jsonpointer v0.21.0 // indirect
@@ -71,14 +74,18 @@ require (
7174
github.com/google/gofuzz v1.2.0 // indirect
7275
github.com/google/uuid v1.6.0 // indirect
7376
github.com/gorilla/mux v1.8.1 // indirect
77+
github.com/gorilla/websocket v1.5.0 // indirect
7478
github.com/h2non/filetype v1.1.3 // indirect
7579
github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c // indirect
7680
github.com/inconshreveable/mousetrap v1.1.0 // indirect
81+
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
82+
github.com/joelanford/ignore v0.1.1 // indirect
7783
github.com/josharian/intern v1.0.0 // indirect
7884
github.com/json-iterator/go v1.1.12 // indirect
7985
github.com/klauspost/compress v1.18.0 // indirect
8086
github.com/mailru/easyjson v0.9.0 // indirect
8187
github.com/moby/locker v1.0.1 // indirect
88+
github.com/moby/spdystream v0.5.0 // indirect
8289
github.com/moby/sys/capability v0.3.0 // indirect
8390
github.com/moby/sys/mountinfo v0.7.2 // indirect
8491
github.com/moby/sys/sequential v0.5.0 // indirect
@@ -87,6 +94,7 @@ require (
8794
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
8895
github.com/modern-go/reflect2 v1.0.2 // indirect
8996
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
97+
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
9098
github.com/nxadm/tail v1.4.8 // indirect
9199
github.com/opencontainers/go-digest v1.0.0 // indirect
92100
github.com/opencontainers/runtime-spec v1.2.0 // indirect
@@ -116,6 +124,7 @@ require (
116124
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
117125
gopkg.in/inf.v0 v0.9.1 // indirect
118126
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
127+
gopkg.in/warnings.v0 v0.1.2 // indirect
119128
gopkg.in/yaml.v3 v3.0.1 // indirect
120129
k8s.io/klog/v2 v2.130.1 // indirect
121130
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect

go.sum

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6
1212
github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y=
1313
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
1414
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
15+
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
16+
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
1517
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
1618
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
1719
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -103,6 +105,12 @@ github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/
103105
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
104106
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
105107
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
108+
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
109+
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
110+
github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA=
111+
github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE=
112+
github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M=
113+
github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc=
106114
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
107115
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
108116
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@@ -166,6 +174,8 @@ github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyE
166174
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
167175
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
168176
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
177+
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
178+
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
169179
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
170180
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
171181
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
@@ -184,6 +194,10 @@ github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyf
184194
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
185195
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
186196
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
197+
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
198+
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
199+
github.com/joelanford/ignore v0.1.1 h1:vKky5RDoPT+WbONrbQBgOn95VV/UPh4ejlyAbbzgnQk=
200+
github.com/joelanford/ignore v0.1.1/go.mod h1:8eho/D8fwQ3rIXrLwE23AaeaGDNXqLE9QJ3zJ4LIPCw=
187201
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
188202
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
189203
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@@ -204,6 +218,8 @@ github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBW
204218
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
205219
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
206220
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
221+
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
222+
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
207223
github.com/moby/sys/capability v0.3.0 h1:kEP+y6te0gEXIaeQhIi0s7vKs/w0RPoH1qPa6jROcVg=
208224
github.com/moby/sys/capability v0.3.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
209225
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
@@ -221,6 +237,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
221237
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
222238
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
223239
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
240+
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
241+
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
224242
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
225243
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
226244
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
@@ -471,6 +489,8 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
471489
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
472490
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
473491
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
492+
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
493+
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
474494
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
475495
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
476496
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package olmv1
2+
3+
import (
4+
"os"
5+
6+
"github.com/spf13/cobra"
7+
"github.com/spf13/pflag"
8+
9+
"github.com/operator-framework/kubectl-operator/internal/cmd/internal/log"
10+
v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action"
11+
"github.com/operator-framework/kubectl-operator/pkg/action"
12+
)
13+
14+
// NewCatalogSearchCmd handles get commands in the form of:
15+
// catalog(s) - this will either list all packages
16+
// from available catalogs if no catalog has been provided.
17+
// The results are restricted to only the contents of specific
18+
// catalogs if either specified by name or label selector.
19+
// results may also be restricted to the contents of a single
20+
// package by name across one or more catalogs.
21+
func NewCatalogSearchCmd(cfg *action.Configuration) *cobra.Command {
22+
i := v1action.NewCatalogSearch(cfg)
23+
i.Logf = log.Printf
24+
25+
cmd := &cobra.Command{
26+
Use: "catalog",
27+
Aliases: []string{"catalogs"},
28+
Args: cobra.RangeArgs(0, 1),
29+
Short: "Search catalogs for installable operators matching parameters",
30+
Run: func(cmd *cobra.Command, args []string) {
31+
catalogContents, err := i.Run(cmd.Context())
32+
if err != nil {
33+
log.Fatalf("failed querying catalog(s): %v", err)
34+
}
35+
switch i.OutputFormat {
36+
case "", "table":
37+
printFormattedDeclCfg(os.Stdout, catalogContents, i.ListVersions)
38+
case "json":
39+
printDeclCfgJSON(os.Stdout, catalogContents)
40+
case "yaml":
41+
printDeclCfgYAML(os.Stdout, catalogContents)
42+
default:
43+
log.Fatalf("unsupported output format %s: allwed formats are (json|yaml|table)", i.OutputFormat)
44+
}
45+
},
46+
}
47+
bindCatalogSearchFlags(cmd.Flags(), i)
48+
49+
return cmd
50+
}
51+
52+
func bindCatalogSearchFlags(fs *pflag.FlagSet, i *v1action.CatalogSearch) {
53+
fs.StringVar(&i.CatalogName, "catalog", "", "Catalog to search on. If not provided, all available catalogs are searched.")
54+
fs.StringVarP(&i.Selector, "selector", "l", "", "Selector (label query) to filter catalogs on, supports '=', '==', and '!='")
55+
fs.StringVarP(&i.OutputFormat, "output", "o", "", "output format. One of: (yaml|json)")
56+
fs.BoolVar(&i.ListVersions, "list-versions", false, "List all versions available for each package")
57+
fs.StringVar(&i.Package, "package", "", "Search for package by name. If empty, all available packages will be listed")
58+
fs.StringVar(&i.CatalogdNamespace, "catalogd-namespace", "olmv1-system", "Namespace for the catalogd controller")
59+
fs.StringVar(&i.Timeout, "timeout", "5m", "Timeout for fetching catalog contents")
60+
// installable vs uninstallable, all versions, channels
61+
// fs.StringVar(&i.showAll, "image", "", "Image reference for the catalog source. Leave unset to retain the current image.")
62+
}

internal/cmd/internal/olmv1/printing.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,22 @@ package olmv1
33
import (
44
"cmp"
55
"fmt"
6+
"io"
67
"os"
78
"slices"
9+
"sort"
10+
"strings"
811
"text/tabwriter"
912
"time"
1013

1114
"github.com/blang/semver/v4"
1215
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1316
"k8s.io/apimachinery/pkg/util/duration"
17+
"k8s.io/apimachinery/pkg/util/json"
1418

1519
olmv1 "github.com/operator-framework/operator-controller/api/v1"
20+
"github.com/operator-framework/operator-registry/alpha/declcfg"
21+
"github.com/operator-framework/operator-registry/alpha/property"
1622
)
1723

1824
func printFormattedExtensions(extensions ...olmv1.ClusterExtension) {
@@ -63,6 +69,125 @@ func printFormattedCatalogs(catalogs ...olmv1.ClusterCatalog) {
6369
_ = tw.Flush()
6470
}
6571

72+
func printFormattedDeclCfg(w io.Writer, catalogDcfg map[string]*declcfg.DeclarativeConfig, listVersions bool) {
73+
var printedHeaders bool
74+
tw := tabwriter.NewWriter(w, 3, 4, 2, ' ', 0)
75+
sortedCatalogs := []string{}
76+
for catalogName := range catalogDcfg {
77+
sortedCatalogs = append(sortedCatalogs, catalogName)
78+
}
79+
sort.Strings(sortedCatalogs)
80+
for _, catalogName := range sortedCatalogs {
81+
dcfg := catalogDcfg[catalogName]
82+
type dcfgPrintMeta struct {
83+
provider string
84+
channels []string
85+
versions []semver.Version
86+
}
87+
pkgProviders := map[string]*dcfgPrintMeta{}
88+
sort.SliceStable(dcfg.Packages, func(i, j int) bool {
89+
return dcfg.Packages[i].Name < dcfg.Packages[j].Name
90+
})
91+
92+
if listVersions {
93+
for _, b := range dcfg.Bundles {
94+
if pkgProviders[b.Package] == nil {
95+
pkgProviders[b.Package] = &dcfgPrintMeta{
96+
versions: []semver.Version{},
97+
provider: getCSVProvider(&b),
98+
}
99+
}
100+
bundleVersion, err := getBundleVersion(&b)
101+
if err == nil {
102+
pkgProviders[b.Package].versions = append(pkgProviders[b.Package].versions, bundleVersion)
103+
}
104+
}
105+
} else {
106+
for _, c := range dcfg.Channels {
107+
if pkgProviders[c.Package] == nil {
108+
pkgProviders[c.Package] = &dcfgPrintMeta{channels: []string{}}
109+
}
110+
pkgProviders[c.Package].channels = append(pkgProviders[c.Package].channels, c.Name)
111+
}
112+
}
113+
114+
for _, p := range dcfg.Packages {
115+
if listVersions {
116+
sort.SliceStable(pkgProviders[p.Name].versions, func(i, j int) bool {
117+
return pkgProviders[p.Name].versions[i].GT(pkgProviders[p.Name].versions[j])
118+
})
119+
for _, v := range pkgProviders[p.Name].versions {
120+
if !printedHeaders {
121+
_, _ = fmt.Fprint(tw, "PACKAGE\tCATALOG\tPROVIDER\tVERSION\n")
122+
printedHeaders = true
123+
}
124+
_, _ = fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n",
125+
p.Name,
126+
catalogName,
127+
pkgProviders[p.Name].provider,
128+
v)
129+
}
130+
} else {
131+
sort.Strings(pkgProviders[p.Name].channels)
132+
if !printedHeaders {
133+
_, _ = fmt.Fprint(tw, "PACKAGE\tCATALOG\tPROVIDER\tCHANNELS\n")
134+
printedHeaders = true
135+
}
136+
_, _ = fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n",
137+
p.Name,
138+
catalogName,
139+
pkgProviders[p.Name].provider,
140+
strings.Join(pkgProviders[p.Name].channels, ","))
141+
}
142+
}
143+
}
144+
if !printedHeaders {
145+
_, _ = fmt.Fprint(tw, "No resources found.\n")
146+
}
147+
_ = tw.Flush()
148+
}
149+
150+
func getBundleVersion(bundle *declcfg.Bundle) (semver.Version, error) {
151+
for _, p := range bundle.Properties {
152+
if p.Type == property.TypePackage {
153+
var pkgProp property.Package
154+
if err := json.Unmarshal(p.Value, &pkgProp); err == nil && len(pkgProp.Version) > 0 {
155+
parsedVersion, err := semver.Parse(pkgProp.Version)
156+
if err != nil {
157+
return semver.Version{}, err
158+
}
159+
return parsedVersion, nil
160+
}
161+
}
162+
}
163+
return semver.Version{}, fmt.Errorf("no version property")
164+
}
165+
166+
func getCSVProvider(bundle *declcfg.Bundle) string {
167+
for _, csvProp := range bundle.Properties {
168+
if csvProp.Type == property.TypeCSVMetadata {
169+
var pkgProp property.CSVMetadata
170+
if err := json.Unmarshal(csvProp.Value, &pkgProp); err == nil && len(pkgProp.Provider.Name) > 0 {
171+
return pkgProp.Provider.Name
172+
}
173+
}
174+
}
175+
return ""
176+
}
177+
178+
func printDeclCfgJSON(w io.Writer, catalogDcfg map[string]*declcfg.DeclarativeConfig) {
179+
for _, dcfg := range catalogDcfg {
180+
_ = declcfg.WriteJSON(*dcfg, w)
181+
}
182+
}
183+
184+
func printDeclCfgYAML(w io.Writer, catalogDcfg map[string]*declcfg.DeclarativeConfig) {
185+
for _, dcfg := range catalogDcfg {
186+
_ = declcfg.WriteYAML(*dcfg, w)
187+
_, _ = w.Write([]byte("---\n"))
188+
}
189+
}
190+
66191
// sortExtensions sorts extensions in place and uses the following sorting order:
67192
// name (asc), version (desc)
68193
func sortExtensions(extensions []olmv1.ClusterExtension) {

internal/cmd/olmv1.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,20 @@ func newOlmV1Cmd(cfg *action.Configuration) *cobra.Command {
5858
}
5959
installCmd.AddCommand(olmv1.NewExtensionInstallCmd(cfg))
6060

61+
searchCmd := &cobra.Command{
62+
Use: "search",
63+
Short: "Search for packages",
64+
Long: "Search one or all available catalogs for packages or versions",
65+
}
66+
searchCmd.AddCommand(olmv1.NewCatalogSearchCmd(cfg))
67+
6168
cmd.AddCommand(
6269
installCmd,
6370
getCmd,
6471
createCmd,
6572
deleteCmd,
6673
updateCmd,
74+
searchCmd,
6775
)
6876

6977
return cmd

internal/pkg/v1/action/catalog_installed_get.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package action
22

33
import (
44
"context"
5+
"fmt"
56

7+
"k8s.io/apimachinery/pkg/labels"
68
"k8s.io/apimachinery/pkg/types"
79
"sigs.k8s.io/controller-runtime/pkg/client"
810

@@ -15,6 +17,8 @@ type CatalogInstalledGet struct {
1517
config *action.Configuration
1618
CatalogName string
1719

20+
Selector string
21+
1822
Logf func(string, ...interface{})
1923
}
2024

@@ -41,7 +45,15 @@ func (i *CatalogInstalledGet) Run(ctx context.Context) ([]olmv1.ClusterCatalog,
4145

4246
// list
4347
var result olmv1.ClusterCatalogList
44-
err := i.config.Client.List(ctx, &result, &client.ListOptions{})
48+
listOptions := &client.ListOptions{}
49+
if len(i.Selector) > 0 {
50+
labelSelector, err := labels.Parse(i.Selector)
51+
if err != nil {
52+
return nil, fmt.Errorf("unable to parse selector %s: %v", i.Selector, err)
53+
}
54+
listOptions.LabelSelector = labelSelector
55+
}
56+
err := i.config.Client.List(ctx, &result, listOptions)
4557

4658
return result.Items, err
4759
}

0 commit comments

Comments
 (0)