From 46fded74451a66dc61ca7f78fdcdc4746cb028a5 Mon Sep 17 00:00:00 2001 From: Marcin Owsiany Date: Tue, 18 Nov 2025 10:30:06 +0100 Subject: [PATCH] feat: add --ignore-kinds to "olm install" cmd Signed-off-by: Marcin Owsiany --- internal/cmd/operator-sdk/olm/install.go | 1 + internal/olm/client/client.go | 27 ++++++++++++++++++++++-- internal/olm/client/client_test.go | 13 ++++++++++-- internal/olm/installer/client.go | 4 ++-- internal/olm/installer/manager.go | 4 +++- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/internal/cmd/operator-sdk/olm/install.go b/internal/cmd/operator-sdk/olm/install.go index 9e5ac57c81a..ffd15a0fce4 100644 --- a/internal/cmd/operator-sdk/olm/install.go +++ b/internal/cmd/operator-sdk/olm/install.go @@ -35,6 +35,7 @@ func newInstallCmd() *cobra.Command { } cmd.Flags().StringVar(&mgr.Version, "version", installer.DefaultVersion, "version of OLM resources to install") + cmd.Flags().StringSliceVar(&mgr.IgnoreKinds, "ignore-kinds", nil, "list of resource kinds to ignore during installation (e.g., \"Deployment,Service\")") mgr.AddToFlagSet(cmd.Flags()) return cmd } diff --git a/internal/olm/client/client.go b/internal/olm/client/client.go index 7f04d23b83b..6b1c23f75db 100644 --- a/internal/olm/client/client.go +++ b/internal/olm/client/client.go @@ -87,10 +87,25 @@ func init() { } type Client struct { - KubeClient client.Client + KubeClient client.Client + ignoredKindsMap map[string]struct{} } -func NewClientForConfig(cfg *rest.Config, httpClient *http.Client) (*Client, error) { +// Option is a function that configures a Client. +type Option func(*Client) + +// WithIgnoredKinds returns an Option that sets the ignored resource kinds +func WithIgnoredKinds(ignoredKinds []string) Option { + return func(c *Client) { + // Create a map for O(1) lookup of ignored kinds + c.ignoredKindsMap = make(map[string]struct{}) + for _, kind := range ignoredKinds { + c.ignoredKindsMap[kind] = struct{}{} + } + } +} + +func NewClientForConfig(cfg *rest.Config, httpClient *http.Client, opts ...Option) (*Client, error) { rm, err := apiutil.NewDynamicRESTMapper(cfg, httpClient) if err != nil { return nil, fmt.Errorf("failed to create dynamic rest mapper: %v", err) @@ -115,6 +130,9 @@ func NewClientForConfig(cfg *rest.Config, httpClient *http.Client) (*Client, err c := &Client{ KubeClient: cl, } + for _, opt := range opts { + opt(c) + } return c, nil } @@ -123,6 +141,11 @@ func (c Client) DoCreate(ctx context.Context, objs ...client.Object) error { kind := obj.GetObjectKind().GroupVersionKind().Kind resourceName := getName(obj.GetNamespace(), obj.GetName()) + if _, ignored := c.ignoredKindsMap[kind]; ignored { + log.Infof(" Skipping %s %q (kind ignored)", kind, resourceName) + continue + } + log.Infof(" Creating %s %q", kind, resourceName) if err := c.safeCreateOneResource(ctx, obj, kind, resourceName); err != nil { diff --git a/internal/olm/client/client_test.go b/internal/olm/client/client_test.go index 2f7a3e382b5..194c1690b2c 100644 --- a/internal/olm/client/client_test.go +++ b/internal/olm/client/client_test.go @@ -273,19 +273,25 @@ var _ = Describe("Client", func() { fakeClient.(*errClient).reset() }) - It("should create all the resources successfully", func() { - cli := Client{KubeClient: fakeClient} + It("should create all the resources successfully, unless ignored", func() { + cli := Client{KubeClient: fakeClient, ignoredKindsMap: map[string]struct{}{"Service": {}}} ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() Expect(cli.DoCreate(ctx, &corev1.Namespace{ + TypeMeta: metav1.TypeMeta{Kind: "Namespace"}, ObjectMeta: metav1.ObjectMeta{Name: "test-ns"}, }, &corev1.Pod{ + TypeMeta: metav1.TypeMeta{Kind: "Pod"}, ObjectMeta: metav1.ObjectMeta{Name: "test-pod", Namespace: "test-ns"}, }, + &corev1.Service{ + TypeMeta: metav1.TypeMeta{Kind: "Service"}, + ObjectMeta: metav1.ObjectMeta{Name: "ignored", Namespace: "test-ns"}, + }, )).To(Succeed()) ns := &corev1.Namespace{} @@ -293,6 +299,9 @@ var _ = Describe("Client", func() { pod := &corev1.Pod{} Expect(fakeClient.Get(context.Background(), client.ObjectKey{Namespace: "test-ns", Name: "test-pod"}, pod)).To(Succeed()) + + svc := &corev1.Service{} + Expect(fakeClient.Get(context.Background(), client.ObjectKey{Namespace: "test-ns", Name: "ignored"}, svc)).ToNot(Succeed()) }) It("should eventually create all the resources successfully", func() { diff --git a/internal/olm/installer/client.go b/internal/olm/installer/client.go index b69b61edce9..0557384102d 100644 --- a/internal/olm/installer/client.go +++ b/internal/olm/installer/client.go @@ -56,13 +56,13 @@ type Client struct { BaseDownloadURL string } -func ClientForConfig(cfg *rest.Config) (*Client, error) { +func ClientForConfig(cfg *rest.Config, opts ...olmresourceclient.Option) (*Client, error) { httpClient, err := rest.HTTPClientFor(cfg) if err != nil { return nil, fmt.Errorf("failed to build an HTTP client for the kubeconfig: %v", err) } - cl, err := olmresourceclient.NewClientForConfig(cfg, httpClient) + cl, err := olmresourceclient.NewClientForConfig(cfg, httpClient, opts...) if err != nil { return nil, fmt.Errorf("failed to get OLM resource client: %v", err) } diff --git a/internal/olm/installer/manager.go b/internal/olm/installer/manager.go index 49905c0efe7..be1997715f0 100644 --- a/internal/olm/installer/manager.go +++ b/internal/olm/installer/manager.go @@ -20,6 +20,7 @@ import ( "sync" "time" + olmresourceclient "github.com/operator-framework/operator-sdk/internal/olm/client" log "github.com/sirupsen/logrus" "github.com/spf13/pflag" "sigs.k8s.io/controller-runtime/pkg/client/config" @@ -39,6 +40,7 @@ type Manager struct { Version string Timeout time.Duration OLMNamespace string + IgnoreKinds []string once sync.Once } @@ -51,7 +53,7 @@ func (m *Manager) initialize() (err error) { return } - client, cerr := ClientForConfig(cfg) + client, cerr := ClientForConfig(cfg, olmresourceclient.WithIgnoredKinds(m.IgnoreKinds)) if cerr != nil { err = fmt.Errorf("failed to create manager client: %v", cerr) return