Skip to content

Commit b4e7a70

Browse files
authored
Refactor for cli and pkg/action decoupling and deduplication (#23)
1 parent fb6f935 commit b4e7a70

14 files changed

+244
-277
lines changed

internal/cmd/catalog_add.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@ package cmd
33
import (
44
"context"
55
"io/ioutil"
6+
"time"
67

78
"github.com/operator-framework/operator-registry/pkg/image/containerdregistry"
89
"github.com/sirupsen/logrus"
910
"github.com/spf13/cobra"
11+
"github.com/spf13/pflag"
1012

1113
"github.com/operator-framework/kubectl-operator/internal/cmd/internal/log"
1214
"github.com/operator-framework/kubectl-operator/internal/pkg/action"
1315
)
1416

1517
func newCatalogAddCmd(cfg *action.Configuration) *cobra.Command {
18+
var timeout time.Duration
1619
a := action.NewCatalogAdd(cfg)
1720
a.Logf = log.Printf
1821

@@ -28,7 +31,7 @@ func newCatalogAddCmd(cfg *action.Configuration) *cobra.Command {
2831
}
2932
},
3033
Run: func(cmd *cobra.Command, args []string) {
31-
ctx, cancel := context.WithTimeout(cmd.Context(), a.AddTimeout)
34+
ctx, cancel := context.WithTimeout(cmd.Context(), timeout)
3235
defer cancel()
3336

3437
a.CatalogSourceName = args[0]
@@ -41,7 +44,18 @@ func newCatalogAddCmd(cfg *action.Configuration) *cobra.Command {
4144
log.Printf("created catalogsource %q\n", cs.Name)
4245
},
4346
}
44-
a.BindFlags(cmd.Flags())
47+
bindCatalogAddFlags(cmd.Flags(), a)
48+
cmd.Flags().DurationVarP(&timeout, "timeout", "t", time.Minute, "the amount of time to wait before cancelling the catalog addition")
4549

4650
return cmd
4751
}
52+
53+
func bindCatalogAddFlags(fs *pflag.FlagSet, a *action.CatalogAdd) {
54+
fs.StringVarP(&a.DisplayName, "display-name", "d", "", "display name of the index")
55+
fs.StringVarP(&a.Publisher, "publisher", "p", "", "publisher of the index")
56+
fs.DurationVar(&a.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount to time to wait before cancelling cleanup")
57+
58+
fs.StringArrayVarP(&a.InjectBundles, "inject-bundles", "b", nil, "inject extra bundles into the index at runtime")
59+
fs.StringVarP(&a.InjectBundleMode, "inject-bundle-mode", "m", "", "mode to use to inject bundles")
60+
_ = fs.MarkHidden("inject-bundle-mode")
61+
}

internal/cmd/operator_describe.go

Lines changed: 13 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ import (
66

77
"github.com/spf13/cobra"
88

9-
operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1"
10-
119
"github.com/operator-framework/kubectl-operator/internal/cmd/internal/log"
1210
"github.com/operator-framework/kubectl-operator/internal/pkg/action"
11+
"github.com/operator-framework/kubectl-operator/internal/pkg/operator"
1312
)
1413

1514
var (
@@ -43,22 +42,17 @@ func newOperatorDescribeCmd(cfg *action.Configuration) *cobra.Command {
4342
// Find the package manifest and package channel for the operator
4443
pms, err := l.Run(cmd.Context())
4544
if err != nil {
46-
log.Fatalf("failed to find operator: %v", err)
45+
log.Fatal(err)
4746
}
4847

4948
// we only expect one item because describe always searches
5049
// for a specific operator by name
51-
pm := &pms[0]
52-
53-
// If the user asked for a channel, look for that
54-
if channel == "" {
55-
channel = pm.Status.DefaultChannel
56-
}
50+
pm := pms[0]
5751

58-
pc, err := getPackageChannel(channel, pm)
52+
pc, err := pm.GetChannel(channel)
5953
if err != nil {
6054
// the requested channel doesn't exist
61-
log.Fatalf("failed to find channel for operator: %v", err)
55+
log.Fatal(err)
6256
}
6357

6458
// prepare what we want to print to the console
@@ -78,10 +72,10 @@ func newOperatorDescribeCmd(cfg *action.Configuration) *cobra.Command {
7872
catHdr+fmt.Sprintf("%s\n\n", pm.Status.CatalogSourceDisplayName),
7973
// available channels
8074
chHdr+fmt.Sprintf("%s\n\n",
81-
strings.Join(getAvailableChannelsWithMarkers(channel, pm), "\n")),
75+
strings.Join(getAvailableChannelsWithMarkers(*pc, pm), "\n")),
8276
// install modes
8377
imHdr+fmt.Sprintf("%s\n\n",
84-
strings.Join(getSupportedInstallModes(pc), "\n")),
78+
strings.Join(pc.GetSupportedInstallModes().List(), "\n")),
8579
// description
8680
sdHdr+fmt.Sprintf("%s\n",
8781
pc.CurrentCSVDesc.Annotations[descAnnot]),
@@ -102,8 +96,9 @@ func newOperatorDescribeCmd(cfg *action.Configuration) *cobra.Command {
10296
}
10397

10498
// add flags to the flagset for this command.
105-
cmd.Flags().StringVarP(&channel, "channel", "c", "", "channel")
106-
cmd.Flags().BoolVarP(&longDescription, "with-long-description", "L", false, "long description")
99+
bindOperatorListAvailableFlags(cmd.Flags(), l)
100+
cmd.Flags().StringVarP(&channel, "channel", "C", "", "package channel to describe")
101+
cmd.Flags().BoolVarP(&longDescription, "with-long-description", "L", false, "include long description")
107102

108103
return cmd
109104
}
@@ -114,45 +109,17 @@ func asHeader(s string) string {
114109
return fmt.Sprintf("== %s ==\n", s)
115110
}
116111

117-
// getPackageChannel returns the package channel specified, or the default if none was specified.
118-
func getPackageChannel(channel string, pm *operatorsv1.PackageManifest) (*operatorsv1.PackageChannel, error) {
119-
var packageChannel *operatorsv1.PackageChannel
120-
for _, ch := range pm.Status.Channels {
121-
ch := ch
122-
if ch.Name == channel {
123-
packageChannel = &ch
124-
}
125-
}
126-
if packageChannel == nil {
127-
return nil, fmt.Errorf("channel %q does not exist for package %q", channel, pm.GetName())
128-
}
129-
return packageChannel, nil
130-
}
131-
132-
// GetSupportedInstallModes returns a string slice representation of install mode
133-
// objects the operator supports.
134-
func getSupportedInstallModes(pc *operatorsv1.PackageChannel) []string {
135-
supportedInstallModes := make([]string, 1)
136-
for _, imode := range pc.CurrentCSVDesc.InstallModes {
137-
if imode.Supported {
138-
supportedInstallModes = append(supportedInstallModes, string(imode.Type))
139-
}
140-
}
141-
142-
return supportedInstallModes
143-
}
144-
145112
// getAvailableChannelsWithMarkers parses all available package channels for a package manifest
146113
// and returns those channel names with indicators for pretty-printing whether they are shown
147114
// or the default channel
148-
func getAvailableChannelsWithMarkers(channel string, pm *operatorsv1.PackageManifest) []string {
115+
func getAvailableChannelsWithMarkers(channel operator.PackageChannel, pm operator.PackageManifest) []string {
149116
channels := make([]string, len(pm.Status.Channels))
150117
for i, ch := range pm.Status.Channels {
151118
n := ch.Name
152-
if ch.IsDefaultChannel(*pm) {
119+
if ch.IsDefaultChannel(pm.PackageManifest) {
153120
n += " (default)"
154121
}
155-
if channel == ch.Name {
122+
if channel.Name == ch.Name {
156123
n += " (shown)"
157124
}
158125
channels[i] = n

internal/cmd/operator_install.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@ package cmd
22

33
import (
44
"context"
5+
"fmt"
6+
"time"
57

8+
"github.com/operator-framework/api/pkg/operators/v1alpha1"
69
"github.com/spf13/cobra"
10+
"github.com/spf13/pflag"
711

812
"github.com/operator-framework/kubectl-operator/internal/cmd/internal/log"
913
"github.com/operator-framework/kubectl-operator/internal/pkg/action"
1014
)
1115

1216
func newOperatorInstallCmd(cfg *action.Configuration) *cobra.Command {
17+
var timeout time.Duration
1318
i := action.NewOperatorInstall(cfg)
1419
i.Logf = log.Printf
1520

@@ -19,7 +24,7 @@ func newOperatorInstallCmd(cfg *action.Configuration) *cobra.Command {
1924
Args: cobra.ExactArgs(1),
2025
Run: func(cmd *cobra.Command, args []string) {
2126
i.Package = args[0]
22-
ctx, cancel := context.WithTimeout(cmd.Context(), i.InstallTimeout)
27+
ctx, cancel := context.WithTimeout(cmd.Context(), timeout)
2328
defer cancel()
2429
csv, err := i.Run(ctx)
2530
if err != nil {
@@ -28,6 +33,23 @@ func newOperatorInstallCmd(cfg *action.Configuration) *cobra.Command {
2833
log.Printf("operator %q installed; installed csv is %q", i.Package, csv.Name)
2934
},
3035
}
31-
i.BindFlags(cmd.Flags())
36+
bindOperatorInstallFlags(cmd.Flags(), i)
37+
cmd.Flags().DurationVarP(&timeout, "timeout", "t", time.Minute, "the amount of time to wait before cancelling the install")
38+
3239
return cmd
3340
}
41+
42+
func bindOperatorInstallFlags(fs *pflag.FlagSet, i *action.OperatorInstall) {
43+
fs.StringVarP(&i.Channel, "channel", "c", "", "subscription channel")
44+
fs.VarP(&i.Approval, "approval", "a", fmt.Sprintf("approval (%s or %s)", v1alpha1.ApprovalManual, v1alpha1.ApprovalAutomatic))
45+
fs.StringVarP(&i.Version, "version", "v", "", "install specific version for operator (default latest)")
46+
fs.StringSliceVarP(&i.WatchNamespaces, "watch", "w", []string{}, "namespaces to watch")
47+
fs.DurationVar(&i.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount to time to wait before cancelling cleanup")
48+
fs.BoolVarP(&i.CreateOperatorGroup, "create-operator-group", "C", false, "create operator group if necessary")
49+
50+
fs.VarP(&i.InstallMode, "install-mode", "i", "install mode")
51+
err := fs.MarkHidden("install-mode")
52+
if err != nil {
53+
panic(`requested flag "install-mode" missing`)
54+
}
55+
}

internal/cmd/operator_list_available.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"time"
1010

1111
"github.com/spf13/cobra"
12+
"github.com/spf13/pflag"
1213
v1 "k8s.io/api/core/v1"
1314
"k8s.io/apimachinery/pkg/util/duration"
1415

@@ -56,6 +57,10 @@ func newOperatorListAvailableCmd(cfg *action.Configuration) *cobra.Command {
5657
_ = tw.Flush()
5758
},
5859
}
59-
l.BindFlags(cmd.Flags())
60+
bindOperatorListAvailableFlags(cmd.Flags(), l)
6061
return cmd
6162
}
63+
64+
func bindOperatorListAvailableFlags(fs *pflag.FlagSet, l *action.OperatorListAvailable) {
65+
fs.VarP(&l.Catalog, "catalog", "c", "catalog to query (default: search all cluster catalogs)")
66+
}

internal/cmd/operator_uninstall.go

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

33
import (
44
"github.com/spf13/cobra"
5+
"github.com/spf13/pflag"
56

67
"github.com/operator-framework/kubectl-operator/internal/cmd/internal/log"
78
"github.com/operator-framework/kubectl-operator/internal/pkg/action"
@@ -23,6 +24,13 @@ func newOperatorUninstallCmd(cfg *action.Configuration) *cobra.Command {
2324
log.Printf("operator %q uninstalled", u.Package)
2425
},
2526
}
26-
u.BindFlags(cmd.Flags())
27+
bindOperatorUninstallFlags(cmd.Flags(), u)
2728
return cmd
2829
}
30+
31+
func bindOperatorUninstallFlags(fs *pflag.FlagSet, u *action.OperatorUninstall) {
32+
fs.BoolVarP(&u.DeleteAll, "delete-all", "X", false, "enable all delete flags")
33+
fs.BoolVar(&u.DeleteCRDs, "delete-crds", false, "delete all owned CRDs and all CRs")
34+
fs.BoolVar(&u.DeleteOperatorGroups, "delete-operator-groups", false, "delete operator groups if no other operators remain")
35+
fs.StringSliceVar(&u.DeleteOperatorGroupNames, "delete-operator-group-names", nil, "specific operator group names to delete (only effective with --delete-operator-groups)")
36+
}

internal/cmd/operator_upgrade.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,25 @@ package cmd
22

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

67
"github.com/spf13/cobra"
8+
"github.com/spf13/pflag"
79

810
"github.com/operator-framework/kubectl-operator/internal/cmd/internal/log"
911
"github.com/operator-framework/kubectl-operator/internal/pkg/action"
1012
)
1113

1214
func newOperatorUpgradeCmd(cfg *action.Configuration) *cobra.Command {
15+
var timeout time.Duration
1316
u := action.NewOperatorUpgrade(cfg)
1417
cmd := &cobra.Command{
1518
Use: "upgrade <operator>",
1619
Short: "Upgrade an operator",
1720
Args: cobra.ExactArgs(1),
1821
Run: func(cmd *cobra.Command, args []string) {
1922
u.Package = args[0]
20-
ctx, cancel := context.WithTimeout(cmd.Context(), u.UpgradeTimeout)
23+
ctx, cancel := context.WithTimeout(cmd.Context(), timeout)
2124
defer cancel()
2225
csv, err := u.Run(ctx)
2326
if err != nil {
@@ -26,6 +29,11 @@ func newOperatorUpgradeCmd(cfg *action.Configuration) *cobra.Command {
2629
log.Printf("operator %q upgraded; installed csv is %q", u.Package, csv.Name)
2730
},
2831
}
29-
u.BindFlags(cmd.Flags())
32+
bindOperatorUpgradeFlags(cmd.Flags(), u)
33+
cmd.Flags().DurationVarP(&timeout, "timeout", "t", time.Minute, "the amount of time to wait before cancelling the upgrade")
3034
return cmd
3135
}
36+
37+
func bindOperatorUpgradeFlags(fs *pflag.FlagSet, u *action.OperatorUpgrade) {
38+
fs.StringVarP(&u.Channel, "channel", "c", "", "subscription channel")
39+
}

internal/pkg/action/catalog_add.go

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
"github.com/operator-framework/api/pkg/operators/v1alpha1"
1818
"github.com/operator-framework/operator-registry/pkg/image"
1919
"github.com/operator-framework/operator-registry/pkg/image/containerdregistry"
20-
"github.com/spf13/pflag"
2120
corev1 "k8s.io/api/core/v1"
2221
apierrors "k8s.io/apimachinery/pkg/api/errors"
2322
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -27,7 +26,7 @@ import (
2726
"k8s.io/client-go/util/retry"
2827
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
2928

30-
"github.com/operator-framework/kubectl-operator/internal/pkg/catalog"
29+
"github.com/operator-framework/kubectl-operator/internal/pkg/catalogsource"
3130
)
3231

3332
const (
@@ -47,7 +46,6 @@ type CatalogAdd struct {
4746
InjectBundleMode string
4847
DisplayName string
4948
Publisher string
50-
AddTimeout time.Duration
5149
CleanupTimeout time.Duration
5250

5351
Logf func(string, ...interface{})
@@ -63,17 +61,6 @@ func NewCatalogAdd(cfg *Configuration) *CatalogAdd {
6361
}
6462
}
6563

66-
func (a *CatalogAdd) BindFlags(fs *pflag.FlagSet) {
67-
fs.StringVarP(&a.DisplayName, "display-name", "d", "", "display name of the index")
68-
fs.StringVarP(&a.Publisher, "publisher", "p", "", "publisher of the index")
69-
fs.DurationVarP(&a.AddTimeout, "timeout", "t", time.Minute, "the amount of time to wait before cancelling the catalog addition")
70-
fs.DurationVar(&a.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount to time to wait before cancelling cleanup")
71-
72-
fs.StringArrayVarP(&a.InjectBundles, "inject-bundles", "b", nil, "inject extra bundles into the index at runtime")
73-
fs.StringVarP(&a.InjectBundleMode, "inject-bundle-mode", "m", "", "mode to use to inject bundles")
74-
_ = fs.MarkHidden("inject-bundle-mode")
75-
}
76-
7764
func (a *CatalogAdd) Run(ctx context.Context) (*v1alpha1.CatalogSource, error) {
7865
var err error
7966
a.registry, err = containerdregistry.NewRegistry(a.RegistryOptions...)
@@ -99,16 +86,16 @@ func (a *CatalogAdd) Run(ctx context.Context) (*v1alpha1.CatalogSource, error) {
9986

10087
a.setDefaults(labels)
10188

102-
opts := []catalog.Option{
103-
catalog.DisplayName(a.DisplayName),
104-
catalog.Publisher(a.Publisher),
89+
opts := []catalogsource.Option{
90+
catalogsource.DisplayName(a.DisplayName),
91+
catalogsource.Publisher(a.Publisher),
10592
}
10693

10794
if len(a.InjectBundles) == 0 {
108-
opts = append(opts, catalog.Image(a.IndexImage))
95+
opts = append(opts, catalogsource.Image(a.IndexImage))
10996
}
11097

111-
cs := catalog.Build(csKey, opts...)
98+
cs := catalogsource.Build(csKey, opts...)
11299
if err := a.config.Client.Create(ctx, cs); err != nil {
113100
return nil, fmt.Errorf("create catalogsource: %v", err)
114101
}

0 commit comments

Comments
 (0)