Skip to content

Commit 1900b43

Browse files
committed
group common flags
Signed-off-by: Ankita Thomas <[email protected]>
1 parent dbbf5fc commit 1900b43

File tree

13 files changed

+491
-206
lines changed

13 files changed

+491
-206
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ require (
2222
k8s.io/apimachinery v0.33.4
2323
k8s.io/cli-runtime v0.33.3
2424
k8s.io/client-go v0.33.4
25+
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
2526
sigs.k8s.io/controller-runtime v0.21.0
2627
sigs.k8s.io/yaml v1.6.0
2728
)
@@ -136,7 +137,6 @@ require (
136137
gopkg.in/yaml.v3 v3.0.1 // indirect
137138
k8s.io/klog/v2 v2.130.1 // indirect
138139
k8s.io/kube-openapi v0.0.0-20250610211856-8b98d1ed966a // indirect
139-
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
140140
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
141141
sigs.k8s.io/randfill v1.0.0 // indirect
142142
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect

internal/cmd/internal/olmv1/catalog_create.go

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,19 @@ import (
1212

1313
olmv1 "github.com/operator-framework/operator-controller/api/v1"
1414
"k8s.io/apimachinery/pkg/runtime/schema"
15+
"k8s.io/apimachinery/pkg/util/errors"
1516
)
1617

18+
type catalogCreateOptions struct {
19+
mutableCatalogOptions
20+
dryRunOptions
21+
}
22+
1723
// NewCatalogCreateCmd allows creating a new catalog
1824
func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command {
1925
i := v1action.NewCatalogCreate(cfg)
2026
i.Logf = log.Printf
27+
var opts catalogCreateOptions
2128

2229
cmd := &cobra.Command{
2330
Use: "catalog <catalog_name> <image_source_ref>",
@@ -27,10 +34,12 @@ func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command {
2734
Run: func(cmd *cobra.Command, args []string) {
2835
i.CatalogName = args[0]
2936
i.ImageSourceRef = args[1]
30-
if len(i.DryRun) > 0 && i.DryRun != v1action.DryRunAll {
31-
log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", i.DryRun, v1action.DryRunAll)
37+
opts.Image = i.ImageSourceRef
38+
if err := opts.validate(); err != nil {
39+
log.Fatalf("failed to parse flags: %s", err.Error())
3240
}
33-
41+
i.DryRun = opts.DryRun
42+
i.Output = opts.Output
3443
catalogObj, err := i.Run(cmd.Context())
3544
if err != nil {
3645
log.Fatalf("failed to create catalog %q: %v\n", i.CatalogName, err)
@@ -50,17 +59,23 @@ func NewCatalogCreateCmd(cfg *action.Configuration) *cobra.Command {
5059
},
5160
}
5261
bindCatalogCreateFlags(cmd.Flags(), i)
62+
bindMutableCatalogFlags(cmd.Flags(), &opts.mutableCatalogOptions)
63+
bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions)
5364

5465
return cmd
5566
}
5667

5768
func bindCatalogCreateFlags(fs *pflag.FlagSet, i *v1action.CatalogCreate) {
58-
fs.Int32Var(&i.Priority, "priority", 0, "priority determines the likelihood of a catalog being selected in conflict scenarios")
59-
fs.BoolVar(&i.Available, "available", true, "determines whether a catalog should be active and serving data. default: true, meaning new catalogs serve their contents by default.")
60-
fs.IntVar(&i.PollIntervalMinutes, "source-poll-interval-minutes", 10, "catalog source polling interval [in minutes]")
61-
fs.StringToStringVar(&i.Labels, "labels", map[string]string{}, "labels to add to the new catalog")
62-
fs.DurationVar(&i.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt")
63-
// sigs.k8s.io/controller-runtime/pkg/client supported dry-run values only.
64-
fs.StringVar(&i.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it if non-empty. One of: (All)")
65-
fs.StringVarP(&i.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)")
69+
fs.DurationVar(&i.CleanupTimeout, "cleanup-timeout", time.Minute, "the amount of time to wait before cancelling cleanup after a failed creation attempt.")
70+
}
71+
72+
func (o *catalogCreateOptions) validate() error {
73+
var errs []error
74+
if err := o.dryRunOptions.validate(); err != nil {
75+
errs = append(errs, err)
76+
}
77+
if err := o.mutableCatalogOptions.validate(); err != nil {
78+
errs = append(errs, err)
79+
}
80+
return errors.NewAggregate(errs)
6681
}

internal/cmd/internal/olmv1/catalog_delete.go

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ import (
1212
"k8s.io/apimachinery/pkg/runtime/schema"
1313
)
1414

15+
type catalogDeleteOptions struct {
16+
dryRunOptions
17+
}
18+
1519
// NewCatalogDeleteCmd allows deleting either a single or all
1620
// existing catalogs
1721
func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command {
18-
d := v1action.NewCatalogDelete(cfg)
19-
d.Logf = log.Printf
22+
i := v1action.NewCatalogDelete(cfg)
23+
i.Logf = log.Printf
24+
var opts catalogDeleteOptions
2025

2126
cmd := &cobra.Command{
2227
Use: "catalog [catalog_name]",
@@ -25,46 +30,46 @@ func NewCatalogDeleteCmd(cfg *action.Configuration) *cobra.Command {
2530
Short: "Delete either a single or all of the existing catalogs",
2631
Run: func(cmd *cobra.Command, args []string) {
2732
if len(args) > 0 {
28-
if d.DeleteAll {
33+
if i.DeleteAll {
2934
log.Fatalf("failed to delete catalog: cannot specify both --all and a catalog name")
3035
}
31-
d.CatalogName = args[0]
36+
i.CatalogName = args[0]
37+
}
38+
if err := opts.validate(); err != nil {
39+
log.Fatalf("failed to parse flags: %s", err.Error())
3240
}
33-
catalogs, err := d.Run(cmd.Context())
41+
i.DryRun = opts.DryRun
42+
i.Output = opts.Output
43+
catalogs, err := i.Run(cmd.Context())
3444
if err != nil {
3545
log.Fatalf("failed to delete catalog(s): %v", err)
3646
}
37-
38-
if len(d.DryRun) == 0 {
47+
if len(i.DryRun) == 0 {
3948
for _, catn := range catalogs {
4049
log.Printf("catalog %s deleted", catn.Name)
4150
}
4251
return
4352
}
44-
if len(d.Output) == 0 {
53+
if len(i.Output) == 0 {
4554
for _, catn := range catalogs {
4655
log.Printf("catalog %s deleted (dry run)\n", catn.Name)
4756
}
4857
return
4958
}
5059

51-
for _, i := range catalogs {
52-
i.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group,
60+
for _, c := range catalogs {
61+
c.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group,
5362
Version: olmv1.GroupVersion.Version, Kind: "ClusterCatalog"})
5463
}
55-
printFormattedCatalogs(d.Output, catalogs...)
56-
for _, catalog := range catalogs {
57-
log.Printf("catalog %q deleted", catalog.Name)
58-
}
64+
printFormattedCatalogs(i.Output, catalogs...)
5965
},
6066
}
61-
bindCatalogDeleteFlags(cmd.Flags(), d)
67+
bindCatalogDeleteFlags(cmd.Flags(), i)
68+
bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions)
6269

6370
return cmd
6471
}
6572

6673
func bindCatalogDeleteFlags(fs *pflag.FlagSet, d *v1action.CatalogDelete) {
6774
fs.BoolVarP(&d.DeleteAll, "all", "a", false, "delete all catalogs")
68-
fs.StringVar(&d.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)")
69-
fs.StringVarP(&d.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)")
7075
}

internal/cmd/internal/olmv1/catalog_search.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func NewCatalogSearchCmd(cfg *action.Configuration) *cobra.Command {
2626
Use: "catalog",
2727
Aliases: []string{"catalogs"},
2828
Args: cobra.RangeArgs(0, 1),
29-
Short: "Search catalogs for installable operators matching parameters",
29+
Short: "Search catalogs for installable packages matching parameters",
3030
Run: func(cmd *cobra.Command, args []string) {
3131
catalogContents, err := i.Run(cmd.Context())
3232
if err != nil {
@@ -40,7 +40,7 @@ func NewCatalogSearchCmd(cfg *action.Configuration) *cobra.Command {
4040
case "yaml":
4141
printDeclCfgYAML(os.Stdout, catalogContents)
4242
default:
43-
log.Fatalf("unsupported output format %s: allwed formats are (json|yaml|table)", i.OutputFormat)
43+
log.Fatalf("unsupported output format %s: allowed formats are (json|yaml|table)", i.OutputFormat)
4444
}
4545
},
4646
}
@@ -50,13 +50,11 @@ func NewCatalogSearchCmd(cfg *action.Configuration) *cobra.Command {
5050
}
5151

5252
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 '!='")
53+
fs.StringVar(&i.CatalogName, "catalog", "", "name of the catalog to search. If not provided, all available catalogs are searched.")
54+
fs.StringVarP(&i.Selector, "selector", "l", "", "selector (label query) to filter catalogs on, supports '=', '==', and '!='")
5555
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.")
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")
6260
}

internal/cmd/internal/olmv1/catalog_update.go

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,49 @@ package olmv1
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
v1action "github.com/operator-framework/kubectl-operator/internal/pkg/v1/action"
89
"github.com/operator-framework/kubectl-operator/pkg/action"
910

1011
olmv1 "github.com/operator-framework/operator-controller/api/v1"
1112
"k8s.io/apimachinery/pkg/runtime/schema"
13+
"k8s.io/apimachinery/pkg/util/errors"
1214
)
1315

16+
type catalogUpdateOptions struct {
17+
mutableCatalogOptions
18+
dryRunOptions
19+
}
20+
1421
// NewCatalogUpdateCmd allows updating a selected clustercatalog
1522
func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command {
1623
i := v1action.NewCatalogUpdate(cfg)
1724
i.Logf = log.Printf
18-
19-
var priority int32
20-
var pollInterval int
21-
var labels map[string]string
22-
var available string
25+
var opts catalogUpdateOptions
2326

2427
cmd := &cobra.Command{
2528
Use: "catalog <catalog>",
2629
Short: "Update a catalog",
2730
Args: cobra.ExactArgs(1),
2831
Run: func(cmd *cobra.Command, args []string) {
2932
i.CatalogName = args[0]
33+
if err := opts.validate(); err != nil {
34+
log.Fatalf("failed to parse flags: %s", err.Error())
35+
}
3036
if cmd.Flags().Changed("priority") {
31-
i.Priority = &priority
37+
i.Priority = &opts.Priority
3238
}
3339
if cmd.Flags().Changed("source-poll-interval-minutes") {
34-
i.PollIntervalMinutes = &pollInterval
40+
i.PollIntervalMinutes = &opts.PollIntervalMinutes
3541
}
3642
if cmd.Flags().Changed("labels") {
37-
i.Labels = labels
38-
}
39-
if len(available) > 0 {
40-
switch available {
41-
case "true":
42-
i.AvailabilityMode = "Available"
43-
case "false":
44-
i.AvailabilityMode = "Unavailable"
45-
default:
46-
log.Fatalf("invalid value for `--available` %s; must be one of (true, false)\n", available)
47-
}
48-
}
49-
if len(i.DryRun) > 0 && i.DryRun != v1action.DryRunAll {
50-
log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", i.DryRun, v1action.DryRunAll)
43+
i.Labels = opts.Labels
5144
}
45+
i.AvailabilityMode = opts.AvailabilityMode
46+
i.DryRun = opts.DryRun
47+
i.Output = opts.Output
5248
catalogObj, err := i.Run(cmd.Context())
5349
if err != nil {
5450
log.Fatalf("failed to update catalog: %v", err)
@@ -68,14 +64,25 @@ func NewCatalogUpdateCmd(cfg *action.Configuration) *cobra.Command {
6864
printFormattedCatalogs(i.Output, *catalogObj)
6965
},
7066
}
71-
cmd.Flags().Int32Var(&priority, "priority", 0, "priority determines the likelihood of a catalog being selected in conflict scenarios")
72-
cmd.Flags().StringVar(&available, "available", "", "determines whether a catalog should be active and serving data. default: true, meaning new catalogs serve their contents by default.")
73-
cmd.Flags().IntVar(&pollInterval, "source-poll-interval-minutes", 5, "catalog source polling interval [in minutes]. Set to 0 or -1 to remove the polling interval.")
74-
cmd.Flags().StringToStringVar(&labels, "labels", map[string]string{}, "labels that will be added to the catalog")
75-
cmd.Flags().StringVar(&i.ImageRef, "image", "", "Image reference for the catalog source. Leave unset to retain the current image.")
76-
cmd.Flags().BoolVar(&i.IgnoreUnset, "ignore-unset", true, "when enabled, any unset flag value will not be changed. Disabling means that for each unset value a default will be used instead")
77-
cmd.Flags().StringVar(&i.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it if non-empty. One of: (All)")
78-
cmd.Flags().StringVarP(&i.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)")
67+
bindCatalogUpdateFlags(cmd.Flags(), i)
68+
bindMutableCatalogFlags(cmd.Flags(), &opts.mutableCatalogOptions)
69+
bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions)
7970

8071
return cmd
8172
}
73+
74+
func bindCatalogUpdateFlags(fs *pflag.FlagSet, i *v1action.CatalogUpdate) {
75+
fs.StringVar(&i.ImageRef, "image", "", "image reference for the catalog source. Leave unset to retain the current image.")
76+
fs.BoolVar(&i.IgnoreUnset, "ignore-unset", true, "set to false to revert all values not specifically set with flags in the command to their default as defined by the clustercatalog customresoucedefinition.")
77+
}
78+
79+
func (o *catalogUpdateOptions) validate() error {
80+
var errs []error
81+
if err := o.dryRunOptions.validate(); err != nil {
82+
errs = append(errs, err)
83+
}
84+
if err := o.mutableCatalogOptions.validate(); err != nil {
85+
errs = append(errs, err)
86+
}
87+
return errors.NewAggregate(errs)
88+
}

internal/cmd/internal/olmv1/extension_delete.go

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ import (
1212
"k8s.io/apimachinery/pkg/runtime/schema"
1313
)
1414

15+
type extensionDeleteOptions struct {
16+
dryRunOptions
17+
}
18+
1519
func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command {
16-
e := v1action.NewExtensionDelete(cfg)
17-
e.Logf = log.Printf
20+
i := v1action.NewExtensionDelete(cfg)
21+
i.Logf = log.Printf
22+
var opts extensionDeleteOptions
1823

1924
cmd := &cobra.Command{
2025
Use: "extension [extension_name]",
@@ -25,42 +30,46 @@ func NewExtensionDeleteCmd(cfg *action.Configuration) *cobra.Command {
2530
cascades to the deletion of all operands.`,
2631
Args: cobra.RangeArgs(0, 1),
2732
Run: func(cmd *cobra.Command, args []string) {
28-
if len(e.DryRun) > 0 && e.DryRun != v1action.DryRunAll {
29-
log.Fatalf("invalid value for `--dry-run` %s, must be one of (%s)\n", e.DryRun, v1action.DryRunAll)
33+
if len(args) > 0 {
34+
if i.DeleteAll {
35+
log.Fatalf("failed to delete extension: cannot specify both --all and an extension name")
36+
}
37+
i.ExtensionName = args[0]
3038
}
31-
if len(args) != 0 {
32-
e.ExtensionName = args[0]
39+
if err := opts.validate(); err != nil {
40+
log.Fatalf("failed to parse flags: %s", err.Error())
3341
}
34-
extensions, err := e.Run(cmd.Context())
42+
i.DryRun = opts.DryRun
43+
i.Output = opts.Output
44+
extensions, err := i.Run(cmd.Context())
3545
if err != nil {
3646
log.Fatalf("failed to delete extension: %v", err)
3747
}
38-
if len(e.DryRun) == 0 {
48+
if len(i.DryRun) == 0 {
3949
for _, extn := range extensions {
4050
log.Printf("extension %s deleted", extn.Name)
4151
}
4252
return
4353
}
44-
if len(e.Output) == 0 {
54+
if len(i.Output) == 0 {
4555
for _, extn := range extensions {
4656
log.Printf("extension %s deleted (dry run)\n", extn.Name)
4757
}
4858
return
4959
}
5060

51-
for _, i := range extensions {
52-
i.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group,
61+
for _, e := range extensions {
62+
e.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{Group: olmv1.GroupVersion.Group,
5363
Version: olmv1.GroupVersion.Version, Kind: olmv1.ClusterExtensionKind})
5464
}
55-
printFormattedExtensions(e.Output, extensions...)
65+
printFormattedExtensions(i.Output, extensions...)
5666
},
5767
}
58-
bindExtensionDeleteFlags(cmd.Flags(), e)
68+
bindExtensionDeleteFlags(cmd.Flags(), i)
69+
bindDryRunFlags(cmd.Flags(), &opts.dryRunOptions)
5970
return cmd
6071
}
6172

6273
func bindExtensionDeleteFlags(fs *pflag.FlagSet, e *v1action.ExtensionDeletion) {
6374
fs.BoolVarP(&e.DeleteAll, "all", "a", false, "delete all extensions")
64-
fs.StringVar(&e.DryRun, "dry-run", "", "display the object that would be sent on a request without applying it. One of: (All)")
65-
fs.StringVarP(&e.Output, "output", "o", "", "output format for dry-run manifests. One of: (json, yaml)")
6675
}

0 commit comments

Comments
 (0)