drifter
drifter

Reputation: 557

Kubernetes operator-sdk : How to delete controller?

We have developed a bunch of controllers and APIs, we need to delete some controllers but we are unable to find a way to delete the API and controllers.

We looked at the available options but no flag to delete the apis.

operator-sdk --help
CLI tool for building Kubernetes extensions and tools.

Usage:
  operator-sdk [flags]
  operator-sdk [command]

Examples:
The first step is to initialize your project:
    operator-sdk init [--plugins=<PLUGIN KEYS> [--project-version=<PROJECT VERSION>]]

<PLUGIN KEYS> is a comma-separated list of plugin keys from the following table
and <PROJECT VERSION> a supported project version for these plugins.

                         Plugin keys | Supported project versions
-------------------------------------+----------------------------
 ansible.sdk.operatorframework.io/v1 |                          3
    declarative.go.kubebuilder.io/v1 |                       2, 3
                go.kubebuilder.io/v2 |                       2, 3
                go.kubebuilder.io/v3 |                          3
    helm.sdk.operatorframework.io/v1 |                          3
  kustomize.common.kubebuilder.io/v1 |                          3
 quarkus.javaoperatorsdk.io/v1-alpha |                          3

For more specific help for the init command of a certain plugins and project version
configuration please run:
    operator-sdk init --help --plugins=<PLUGIN KEYS> [--project-version=<PROJECT VERSION>]

Default plugin keys: "go.kubebuilder.io/v3"
Default project version: "3"


Available Commands:
  alpha            Alpha-stage subcommands
  bundle           Manage operator bundle metadata
  cleanup          Clean up an Operator deployed with the 'run' subcommand
  completion       Load completions for the specified shell
  create           Scaffold a Kubernetes API or webhook
  edit             Update the project configuration
  generate         Invokes a specific generator
  help             Help about any command
  init             Initialize a new project
  olm              Manage the Operator Lifecycle Manager installation in your cluster
  pkgman-to-bundle Migrates packagemanifests to bundles
  run              Run an Operator in a variety of environments
  scorecard        Runs scorecard
  version          Print the operator-sdk version

Flags:
  -h, --help                     help for operator-sdk
      --plugins strings          plugin keys to be used for this subcommand execution
      --project-version string   project version (default "3")
      --verbose                  Enable verbose logging

Upvotes: 3

Views: 1727

Answers (1)

asmacdo
asmacdo

Reputation: 663

There is not an automated way to remove APIs via the operator-sdk.

There are a couple ways to do it. If you're operator is fairly simple, you could just scaffold a new operator and copy the code you want into it.

Otherwise, you'll have to remove it by hand. I created a dummy operator, commited it, and then added a new API to get this diff which can be used to see what you'll need to delete. (This is using the master branch, it may be different depending on the version you are using.)

diff --git a/PROJECT b/PROJECT
index ca36be5..0bb71be 100644
--- a/PROJECT
+++ b/PROJECT
@@ -16,4 +16,13 @@ resources:
   kind: Memcached
   path: github.com/example/memcached-operator/api/v1alpha1
   version: v1alpha1
+- api:
+    crdVersion: v1
+    namespaced: true
+  controller: true
+  domain: example.com
+  group: cache
+  kind: Memcached2
+  path: github.com/example/memcached-operator/api/v1alpha1
+  version: v1alpha1
 version: "3"
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 7730cf5..8211ded 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -51,6 +51,95 @@ func (in *Memcached) DeepCopyObject() runtime.Object {
    return nil
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Memcached2) DeepCopyInto(out *Memcached2) {
+   *out = *in
+   out.TypeMeta = in.TypeMeta
+   in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+   out.Spec = in.Spec
+   out.Status = in.Status
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Memcached2.
+func (in *Memcached2) DeepCopy() *Memcached2 {
+   if in == nil {
+       return nil
+   }
+   out := new(Memcached2)
+   in.DeepCopyInto(out)
+   return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Memcached2) DeepCopyObject() runtime.Object {
+   if c := in.DeepCopy(); c != nil {
+       return c
+   }
+   return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Memcached2List) DeepCopyInto(out *Memcached2List) {
+   *out = *in
+   out.TypeMeta = in.TypeMeta
+   in.ListMeta.DeepCopyInto(&out.ListMeta)
+   if in.Items != nil {
+       in, out := &in.Items, &out.Items
+       *out = make([]Memcached2, len(*in))
+       for i := range *in {
+           (*in)[i].DeepCopyInto(&(*out)[i])
+       }
+   }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Memcached2List.
+func (in *Memcached2List) DeepCopy() *Memcached2List {
+   if in == nil {
+       return nil
+   }
+   out := new(Memcached2List)
+   in.DeepCopyInto(out)
+   return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Memcached2List) DeepCopyObject() runtime.Object {
+   if c := in.DeepCopy(); c != nil {
+       return c
+   }
+   return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Memcached2Spec) DeepCopyInto(out *Memcached2Spec) {
+   *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Memcached2Spec.
+func (in *Memcached2Spec) DeepCopy() *Memcached2Spec {
+   if in == nil {
+       return nil
+   }
+   out := new(Memcached2Spec)
+   in.DeepCopyInto(out)
+   return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Memcached2Status) DeepCopyInto(out *Memcached2Status) {
+   *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Memcached2Status.
+func (in *Memcached2Status) DeepCopy() *Memcached2Status {
+   if in == nil {
+       return nil
+   }
+   out := new(Memcached2Status)
+   in.DeepCopyInto(out)
+   return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *MemcachedList) DeepCopyInto(out *MemcachedList) {
    *out = *in
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index 8b7bb5b..5d83219 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -3,17 +3,20 @@
 # It should be run by config/default
 resources:
 - bases/cache.example.com_memcacheds.yaml
+- bases/cache.example.com_memcached2s.yaml
 #+kubebuilder:scaffold:crdkustomizeresource
 
 patchesStrategicMerge:
 # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
 # patches here are for enabling the conversion webhook for each CRD
 #- patches/webhook_in_memcacheds.yaml
+#- patches/webhook_in_memcached2s.yaml
 #+kubebuilder:scaffold:crdkustomizewebhookpatch
 
 # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
 # patches here are for enabling the CA injection for each CRD
 #- patches/cainjection_in_memcacheds.yaml
+#- patches/cainjection_in_memcached2s.yaml
 #+kubebuilder:scaffold:crdkustomizecainjectionpatch
 
 # the following config is for teaching kustomize how to do kustomization for CRDs.
diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml
index 42654aa..9c62d32 100644
--- a/config/samples/kustomization.yaml
+++ b/config/samples/kustomization.yaml
@@ -1,4 +1,5 @@
 ## Append samples you want in your CSV to this file as resources ##
 resources:
 - cache_v1alpha1_memcached.yaml
+- cache_v1alpha1_memcached2.yaml
 #+kubebuilder:scaffold:manifestskustomizesamples
diff --git a/controllers/suite_test.go b/controllers/suite_test.go
index 97d4bfb..ffce919 100644
--- a/controllers/suite_test.go
+++ b/controllers/suite_test.go
@@ -65,6 +65,9 @@ var _ = BeforeSuite(func() {
    err = cachev1alpha1.AddToScheme(scheme.Scheme)
    Expect(err).NotTo(HaveOccurred())
 
+   err = cachev1alpha1.AddToScheme(scheme.Scheme)
+   Expect(err).NotTo(HaveOccurred())
+
    //+kubebuilder:scaffold:scheme
 
    k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
diff --git a/main.go b/main.go
index b2bedfd..443397e 100644
--- a/main.go
+++ b/main.go
@@ -85,6 +85,13 @@ func main() {
        setupLog.Error(err, "unable to create controller", "controller", "Memcached")
        os.Exit(1)
    }
+   if err = (&controllers.Memcached2Reconciler{
+       Client: mgr.GetClient(),
+       Scheme: mgr.GetScheme(),
+   }).SetupWithManager(mgr); err != nil {
+       setupLog.Error(err, "unable to create controller", "controller", "Memcached2")
+       os.Exit(1)
+   }
    //+kubebuilder:scaffold:builder
 
    if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {

I'm not sure if this is something that we could add to the operator-sdk right now, but it would be worth filing an issue, which we will discuss at our triage meeting. https://github.com/operator-framework/operator-sdk/issues/new?assignees=&labels=&template=feature-request.md&title=

Upvotes: 0

Related Questions