Skip to content

Commit 9ae44c1

Browse files
committed
Add commands to list and get olmv1 operators and catalogs
Signed-off-by: Artur Zych <[email protected]>
1 parent 1acf90b commit 9ae44c1

File tree

13 files changed

+344
-0
lines changed

13 files changed

+344
-0
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ require (
1111
github.com/onsi/gomega v1.36.2
1212
github.com/opencontainers/image-spec v1.1.0
1313
github.com/operator-framework/api v0.29.0
14+
github.com/operator-framework/catalogd v1.1.0
1415
github.com/operator-framework/operator-controller v1.1.0
1516
github.com/operator-framework/operator-lifecycle-manager v0.23.1
1617
github.com/operator-framework/operator-registry v1.50.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE
242242
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
243243
github.com/operator-framework/api v0.29.0 h1:TxAR8RCO+I4FjRrY4PSMgnlmbxNWeD8pzHXp7xwHNmw=
244244
github.com/operator-framework/api v0.29.0/go.mod h1:0whQE4mpMDd2zyHkQe+bFa3DLoRs6oGWCbu8dY/3pyc=
245+
github.com/operator-framework/catalogd v1.1.0 h1:mu2DYL5mpREEAAP+uPG+CMSsfsJkgrIasgLRG8nvwJg=
246+
github.com/operator-framework/catalogd v1.1.0/go.mod h1:8Je9CqMPwhNgRoqGX5OPsLYHsEoTDvPnELLLKRw1RHE=
245247
github.com/operator-framework/operator-controller v1.1.0 h1:h0b1SSuv9ZiIgI8dTuutSPVL4uIeyvTW3gOB2szkBMQ=
246248
github.com/operator-framework/operator-controller v1.1.0/go.mod h1:dJIt5/gfm1n3y9IeX4kpSlpu4CFq8WFVHU2n9ZDVUkA=
247249
github.com/operator-framework/operator-lifecycle-manager v0.23.1 h1:Xw2ml1T4W2ieoFaVwanW/eFlZ11yAOJZUpUI8RLSql8=
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package olmv1
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
6+
"github.com/operator-framework/kubectl-operator/internal/cmd/internal/log"
7+
v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action"
8+
"github.com/operator-framework/kubectl-operator/pkg/action"
9+
)
10+
11+
func NewCatalogInstalledGetCmd(cfg *action.Configuration) *cobra.Command {
12+
i := v1action.NewCatalogInstalledGet(cfg)
13+
i.Logf = log.Printf
14+
15+
cmd := &cobra.Command{
16+
Use: "catalog",
17+
Short: "Get details of an installed catalog",
18+
Args: cobra.ExactArgs(1),
19+
Run: func(cmd *cobra.Command, args []string) {
20+
i.CatalogName = args[0]
21+
installedCatalog, err := i.Run(cmd.Context())
22+
if err != nil {
23+
log.Fatalf("failed getting installed catalog %q: %v", i.CatalogName, err)
24+
}
25+
26+
printFormattedCatalogs(installedCatalog)
27+
},
28+
}
29+
30+
return cmd
31+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package olmv1
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
6+
"github.com/operator-framework/kubectl-operator/internal/cmd/internal/log"
7+
v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action"
8+
"github.com/operator-framework/kubectl-operator/pkg/action"
9+
)
10+
11+
func NewCatalogInstalledListCmd(cfg *action.Configuration) *cobra.Command {
12+
i := v1action.NewCatalogInstalledList(cfg)
13+
i.Logf = log.Printf
14+
15+
cmd := &cobra.Command{
16+
Use: "catalogs",
17+
Short: "List installed catalogs",
18+
Run: func(cmd *cobra.Command, args []string) {
19+
catalogs, err := i.Run(cmd.Context())
20+
if err != nil {
21+
log.Fatalf("failed listing installed catalogs: %v", err)
22+
}
23+
24+
if len(catalogs) == 0 {
25+
log.Print("No resources found")
26+
return
27+
}
28+
29+
printFormattedCatalogs(catalogs...)
30+
},
31+
}
32+
33+
return cmd
34+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package olmv1
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
6+
"github.com/operator-framework/kubectl-operator/internal/cmd/internal/log"
7+
v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action"
8+
"github.com/operator-framework/kubectl-operator/pkg/action"
9+
)
10+
11+
func NewOperatorInstalledGetCmd(cfg *action.Configuration) *cobra.Command {
12+
i := v1action.NewOperatorInstalledGet(cfg)
13+
i.Logf = log.Printf
14+
15+
cmd := &cobra.Command{
16+
Use: "operator",
17+
Short: "Get details of an installed operator",
18+
Args: cobra.ExactArgs(1),
19+
Run: func(cmd *cobra.Command, args []string) {
20+
i.OperatorName = args[0]
21+
installedExtension, err := i.Run(cmd.Context())
22+
if err != nil {
23+
log.Fatalf("failed getting installed operator %q: %v", err)
24+
}
25+
26+
printFormattedOperators(installedExtension)
27+
},
28+
}
29+
30+
return cmd
31+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package olmv1
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
6+
"github.com/operator-framework/kubectl-operator/internal/cmd/internal/log"
7+
v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action"
8+
"github.com/operator-framework/kubectl-operator/pkg/action"
9+
)
10+
11+
func NewOperatorInstalledListCmd(cfg *action.Configuration) *cobra.Command {
12+
i := v1action.NewOperatorInstalledList(cfg)
13+
i.Logf = log.Printf
14+
15+
cmd := &cobra.Command{
16+
Use: "operators",
17+
Short: "List installed operators",
18+
Run: func(cmd *cobra.Command, args []string) {
19+
installedExtensions, err := i.Run(cmd.Context())
20+
if err != nil {
21+
log.Fatalf("failed listing installed operators: %v", err)
22+
}
23+
24+
if len(installedExtensions) == 0 {
25+
log.Print("No resources found")
26+
return
27+
}
28+
29+
printFormattedOperators(installedExtensions...)
30+
},
31+
}
32+
33+
return cmd
34+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package olmv1
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"text/tabwriter"
7+
"time"
8+
9+
catalogdv1 "github.com/operator-framework/catalogd/api/v1"
10+
olmv1 "github.com/operator-framework/operator-controller/api/v1"
11+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/apimachinery/pkg/util/duration"
13+
)
14+
15+
func printFormattedOperators(extensions ...olmv1.ClusterExtension) {
16+
tw := tabwriter.NewWriter(os.Stdout, 3, 4, 2, ' ', 0)
17+
_, _ = fmt.Fprint(tw, "NAME\tINSTALLED BUNDLE\tVERSION\tSOURCE TYPE\tINSTALLED\tPROGRESSING\tAGE\n")
18+
for _, ext := range extensions {
19+
20+
age := time.Since(ext.CreationTimestamp.Time)
21+
_, _ = fmt.Fprintf(tw, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
22+
ext.Name,
23+
ext.Status.Install.Bundle.Name,
24+
ext.Status.Install.Bundle.Version,
25+
ext.Spec.Source.SourceType,
26+
status(ext.Status.Conditions, olmv1.TypeInstalled),
27+
status(ext.Status.Conditions, olmv1.TypeProgressing),
28+
duration.HumanDuration(age),
29+
)
30+
}
31+
_ = tw.Flush()
32+
}
33+
34+
func printFormattedCatalogs(catalogs ...catalogdv1.ClusterCatalog) {
35+
tw := tabwriter.NewWriter(os.Stdout, 3, 4, 2, ' ', 0)
36+
_, _ = fmt.Fprint(tw, "NAME\tLASTUNPACKED\tSERVING\tAGE\n")
37+
for _, cat := range catalogs {
38+
39+
age := time.Since(cat.CreationTimestamp.Time)
40+
lastUnpacked := time.Since(cat.Status.LastUnpacked.Time)
41+
_, _ = fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n",
42+
cat.Name,
43+
duration.HumanDuration(lastUnpacked),
44+
status(cat.Status.Conditions, catalogdv1.TypeServing),
45+
duration.HumanDuration(age),
46+
)
47+
}
48+
_ = tw.Flush()
49+
}
50+
51+
func status(conditions []metav1.Condition, typ string) string {
52+
for _, condition := range conditions {
53+
if condition.Type == typ {
54+
return string(condition.Status)
55+
}
56+
}
57+
58+
return "Unknown"
59+
}

internal/cmd/olmv1.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,33 @@ func newOlmV1Cmd(cfg *action.Configuration) *cobra.Command {
1414
Long: "Manage operators via OLMv1 in a cluster from the command line.",
1515
}
1616

17+
// use get <resource_type>
18+
getCmd := &cobra.Command{
19+
Use: "get",
20+
Short: "Get details of a specific OLMv1 resource",
21+
Long: "Get details of a specific OLMv1 resource",
22+
}
23+
getCmd.AddCommand(
24+
olmv1.NewOperatorInstalledGetCmd(cfg),
25+
olmv1.NewCatalogInstalledGetCmd(cfg),
26+
)
27+
28+
// use list <resource_type>
29+
listCmd := &cobra.Command{
30+
Use: "list",
31+
Short: "List OLMv1 resources",
32+
Long: "List OLMv1 resources",
33+
}
34+
listCmd.AddCommand(
35+
olmv1.NewOperatorInstalledListCmd(cfg),
36+
olmv1.NewCatalogInstalledListCmd(cfg),
37+
)
38+
1739
cmd.AddCommand(
1840
olmv1.NewOperatorInstallCmd(cfg),
1941
olmv1.NewOperatorUninstallCmd(cfg),
42+
getCmd,
43+
listCmd,
2044
)
2145

2246
return cmd
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package action
2+
3+
import (
4+
"context"
5+
6+
olmv1catalogd "github.com/operator-framework/catalogd/api/v1"
7+
"k8s.io/apimachinery/pkg/types"
8+
9+
"github.com/operator-framework/kubectl-operator/pkg/action"
10+
)
11+
12+
type CatalogInstalledGet struct {
13+
config *action.Configuration
14+
CatalogName string
15+
16+
Logf func(string, ...interface{})
17+
}
18+
19+
func NewCatalogInstalledGet(cfg *action.Configuration) *CatalogInstalledGet {
20+
return &CatalogInstalledGet{
21+
config: cfg,
22+
Logf: func(string, ...interface{}) {},
23+
}
24+
}
25+
26+
func (i *CatalogInstalledGet) Run(ctx context.Context) (olmv1catalogd.ClusterCatalog, error) {
27+
var result olmv1catalogd.ClusterCatalog
28+
29+
opKey := types.NamespacedName{Name: i.CatalogName}
30+
err := i.config.Client.Get(ctx, opKey, &result)
31+
32+
return result, err
33+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package action
2+
3+
import (
4+
"context"
5+
6+
olmv1catalogd "github.com/operator-framework/catalogd/api/v1"
7+
"sigs.k8s.io/controller-runtime/pkg/client"
8+
9+
"github.com/operator-framework/kubectl-operator/pkg/action"
10+
)
11+
12+
type CatalogInstalledList struct {
13+
config *action.Configuration
14+
15+
Logf func(string, ...interface{})
16+
}
17+
18+
func NewCatalogInstalledList(cfg *action.Configuration) *CatalogInstalledList {
19+
return &CatalogInstalledList{
20+
config: cfg,
21+
Logf: func(string, ...interface{}) {},
22+
}
23+
}
24+
25+
func (i *CatalogInstalledList) Run(ctx context.Context) ([]olmv1catalogd.ClusterCatalog, error) {
26+
var result olmv1catalogd.ClusterCatalogList
27+
err := i.config.Client.List(ctx, &result, &client.ListOptions{})
28+
29+
return result.Items, err
30+
}

0 commit comments

Comments
 (0)