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

huangapple go评论80阅读模式
英文:

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

问题

抱歉,我是一个语言模型,无法直接运行代码。但是我可以帮你解释一下代码中的问题。

根据你提供的代码和错误信息,问题出在DeleteOldAny函数中的resource参数上。错误信息指出interface{}类型没有实现k8s.io/apimachinery/pkg/runtime.Object接口的DeepCopyObject方法。

在Go语言中,接口类型是隐式实现的,而不是显式实现的。这意味着你不能将一个接口类型的指针传递给一个期望接口类型的函数。在你的代码中,resource参数的类型是interface{},而不是一个接口类型。

要解决这个问题,你可以将resource参数的类型更改为一个接口类型,该接口类型实现了DeepCopyObject方法。根据你提供的代码,你可以使用batchv1beta1.CronJob作为接口类型,因为它是一个结构体,并且实现了DeepCopyObject方法。修改代码如下:

func DeleteOldAny(c client.Client, ctx context.Context, name string, key client.ObjectKey, resource runtime.Object) 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
}

然后在调用DeleteOldAny函数时,将&cronJob作为resource参数传递:

return DeleteOldAny(c, ctx, name, key, &cronJob)

这样修改后,你应该能够正确地使用DeleteOldAny函数,并且可以在不同类型上重用它。

希望这可以帮助到你!如果你还有其他问题,请随时提问。

英文:

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?

答案1

得分: 1

func (client.Reader).Get(ctx context.Context, key types.NamespacedName, obj client.Object) error
Get从Kubernetes集群中检索给定对象键的objobj必须是一个结构体指针以便可以使用服务器返回的响应更新obj

所以这个想法是正确的,采用模块化的方法并停止重用代码。

但是实现是错误的,obj应该是您尝试从集群中获取的资源,应该将其作为结构体指针传递给函数。

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

这里的resource应该是一个结构体,就像Get,delete等函数期望传递指向相应对象的指针一样。

英文:
func (client.Reader).Get(ctx context.Context, key types.NamespacedName, obj client.Object) error
Get retrieves an obj for the given object key from the Kubernetes Cluster. obj must be a struct pointer so that obj can be updated with the response returned by the Server.

so the idea is right to have modular approach and stop reusing the code .

But implementation is wrong , the obj would be the resource you are trying to fetch from cluster which should be passed in the function as a struct pointer.

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

here resource should be a struct as Get , delete etc. expects as pointer to the respective object to be passed .

答案2

得分: 0

基本上答案是使用unstructured包

我认为你不能在没有具体类型的情况下使用client.Get(),这太荒谬了。Go确实是一种僵硬而冗长的语言,不是吗?

英文:

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?

huangapple
  • 本文由 发表于 2022年6月23日 20:14:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/72729990.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定