为了账号安全,请及时绑定邮箱和手机立即绑定

无论类型如何反序列化 ObjectMeta

无论类型如何反序列化 ObjectMeta

Go
波斯汪 2023-06-26 17:21:34
如何在事先metav1.ObjectMeta不知道对象的情况下灵活地解码 k8s API 对象并检查其顶级结构?Kind我正在编写一个准入控制器端点,它将metav1.AdmissionReview对象的Request.Object.Raw字段解组为基于该Request.Kind字段的具体对象 - 例如if kind == "Pod" {    var pod core.Pod    // ...    if _, _, err := deserializer.Decode(admissionReview.Request.Object.Raw, nil, &pod); err != nil {        return nil, err    }    annotations := pod.ObjectMeta.Annotations    // inspect/validate the annotations...这需要预先了解所有可能的类型,或者可能要求用户提供map[kind]corev1.Object我们可以使用的更灵活的类型。我想要实现的目标是更接近:var objMeta core.ObjectMetaif _, _, err := deserializer.Decode(admissionReview.Request.Object.Raw, nil, &objMeta); err != nil {        return nil, err}// if objMeta is populated, validate the fields, else// assume it is an object that does not define an ObjectMeta// as part of its schema.这可能吗?k8s API 表面相当广泛,我已经浏览了metav1 godoc、 corev1 godoc 和https://cs.k8s.io的现有技术,但没有一个像样的例子。我发现的最接近的可能是ObjectMetaAccessor接口,但我需要从AdmissionReview.Request.Object(type runtime.RawExtension) 到第runtime.Object一个。
查看完整描述

2 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

我最近发现了一种方法可以做到这一点,让我在这里描述一下:


快速免责声明:我使用了admission/v1,但从未使用admission/v1beta1 进行过测试,它的工作原理应该是相同的。


的数据类型admissionReview.Request.Object为runtime.RawExtension,并且提供了将 转换为 a 的k8s.io/apimachinery/pkg/runtime方法。该方法称为. 从那里,您可以轻松地转换为数据类型,该数据类型具有可以通过简单的 getter 方法访问的对象的所有字段。runtime.RawExtensionruntime.Objectruntime.Convert_runtime_RawExtension_To_runtime_Object(...)unstructured.UnstructuredMetaV1


这是一个可以让您完成此任务的代码片段:


import (

    // ...

    "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

    "k8s.io/apimachinery/pkg/runtime"

    // ...

)


// ...


func dummyFunc(ar *v1.AdmissionReview) {

    // ...

    var obj runtime.Object

    var scope conversion.Scope // While not actually used within the function, need to pass in

    err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&ar.Request.Object, &obj, scope)

    if err != nil {

        // ...

    }


    innerObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)

    if err != nil {

        // ...

    }

    u := unstructured.Unstructured{Object: innerObj}

    // Now the `u` variable has all the meta info available with simple getters.

    // Sample:

    labels := u.GetLabels()

    kind := u.GetKind()

    // etc.

    // ...

}

查看完整回答
反对 回复 2023-06-26
?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

我相信你找不到你要找的东西,因为在解码对象时,Kubernetes 使用GetObjectKind并将结果与方案进行比较,以将对象转换为具体类型,而不是使用一些通用的方法并与字段交互对象的具体类型而不知道它的具体类型。

所以你可以使用反射来代替,比如:

k8sObjValue := reflect.ValueOf(admissionReview.Request.Object.Raw).Elem()

k8sObjObjectMeta := k8sObjValue.FieldByName("ObjectMeta")

annotations, ok := k8sObjObjectMeta.FieldByName("Annotations").Interface().(map[string]string)

if !ok {

    panic("failed to retrieve annotations")

}

编辑:


或者更接近您的要求,转换为 ObjectMeta 对象


k8sObjValue := reflect.ValueOf(admissionReview.Request.Object.Raw).Elem()

objMeta, ok := k8sObjValue.FieldByName("ObjectMeta").Interface().(core.ObjectMeta)

if !ok {

    panic("failed to retrieve object metadata")

}


查看完整回答
反对 回复 2023-06-26
?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

看来有两种可能:

  1. 要么该字段Object应该已经包含正确的对象实例

  2. 尝试使用此处的转换器


查看完整回答
反对 回复 2023-06-26
  • 2 回答
  • 0 关注
  • 203 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信