gokubernetesoperator-sdk

How can I make a function that works on any type from the k8s package?


Sorry I'm quite a noob at Go so hope this isn't a stupid question. I know pointers in a general sense but struggling with Go semantics.

I can't get this to work:

func DeleteOldCronJob(c client.Client, ctx context.Context, namespace string, name string) error {
    cronJob := batchv1beta1.CronJob{}
    key := client.ObjectKey{
        Namespace: namespace,
        Name:      name,
    }
    return DeleteOldAny(c, ctx, name, key, &cronJob)
}

func DeleteOldAny(c client.Client, ctx context.Context, name string, key client.ObjectKey, resource interface{}) error {
    err := c.Get(ctx, key, resource)

    if err == nil {
        err := c.Delete(ctx, resource)
        if err != nil {
            return err
        }
    } else {
        return err
    }

    return nil
}

I get an error:

interface {} does not implement "k8s.io/apimachinery/pkg/runtime".Object (missing DeepCopyObject method)

The point is so that I can reuse DeleteOldAny on multiple different types, to make my codebase more compact (I could just copy+paste DeleteOldCronjob and change the type). As far as I read, pointers to interfaces in Go are usually wrong. Also, the k8s type I'm importing is just a struct. So, I thought since it's a struct not an interface I should pass resource a a pointer like:

        err := c.Get(ctx, key, &resource)

But that gives me another error:

*interface {} is pointer to interface, not interface

So I'm a bit stuck. Am I doomed to copy+paste the same function for each type or is it a simple syntax mistake I'm making?


Solution

  • Pretty much the answer is to use the unstructured package.

    I don't think you can do client.Get() without a concrete type, which is ridiculous. Go really is a stiff and verbose language, isn't it?